'use strict';
/**
 * Telemetry collector for the BrightSign shell — fills the SAME snapshot schema the plane ingests (see
 * desktop/telemetry.js and documentation/telemetria-diagnostica.md), but sourced from `@brightsign/*`.
 *
 *   collectBasic(): model/serial/OS/network/storage/memory — cheap, runs on every heartbeat.
 *   collectDeep():  adds panel temperature (deviceinfo.getTemperature) + a native BrightSign block.
 *
 * BrightSign has no battery and no `uptime` property on deviceinfo; we derive uptime from Node os.uptime().
 */
const device = require('./device');

let os = null;
try {
	os = require('os');
} catch (e) {
	/* not all BrightSign Node builds expose full os; guard every use */
}

const BYTES_GB = 1024 * 1024 * 1024;
const round = (n, d = 1) => (typeof n === 'number' && isFinite(n) ? Number(n.toFixed(d)) : null);

function memory() {
	if (!os || !os.totalmem) return null;
	try {
		return { totalGb: round(os.totalmem() / BYTES_GB), freeGb: round(os.freemem() / BYTES_GB) };
	} catch (e) {
		return null;
	}
}

async function collectBasic(extra) {
	const e = extra || {};
	const dev = device.deviceSummary();
	const storage = await device.storageStats('SD').catch(() => null);
	return {
		level: 'basic',
		at: new Date().toISOString(),
		brand: 'BrightSign',
		model: dev.model || null,
		serial: dev.serial || null,
		osPlatform: 'brightsign',
		osVersion: dev.osVersion || null,
		osRelease: dev.bootVersion || null,
		arch: (os && os.arch && os.arch()) || null,
		family: dev.family || null,
		hostname: (os && os.hostname && os.hostname()) || null,
		uptimeSec: os && os.uptime ? Math.round(os.uptime()) : null, // deviceinfo has no uptime property
		memory: memory(),
		storage: storage,
		network: device.networkInterfaces(),
		timezone: tz(),
		localTime: new Date().toString(),
		appVersion: e.appVersion || null,
		appVersionCode: e.appVersionCode || null,
		bundleVersion: e.bundleVersion || null,
		appCacheBytes: typeof e.appCacheBytes === 'number' ? e.appCacheBytes : null,
		displays: e.displays && e.displays.length ? e.displays : safeDisplays(), // A-8: enumerate HDMI outputs
		displayIndex: typeof e.displayIndex === 'number' ? e.displayIndex : null,
		orientation: e.orientation || null,
		// A-4: which web features the runtime actually supports (Series 4 / Chromium ≤87 has no Service Worker
		// → offline store-and-play degrades). The page probes this and hands it to the agent.
		browserCapabilities: e.browserCapabilities || null,
		maintenance: !!e.maintenance,
		deepTelemetry: !!e.deepTelemetry,
		debugOverlay: !!e.debugOverlay,
		autostart: true, // autorun.brs is inherent on BrightSign
		root: false,
		temperatureC: null, // deep mode fills it
	};
}

async function collectDeep(extra) {
	const base = await collectBasic(extra);
	const temp = await device.deviceTemperatureC().catch(() => null);
	return Object.assign({}, base, {
		level: 'deep',
		temperatureC: temp,
		brightsign: {
			family: base.family,
			model: base.model,
			serial: base.serial,
			osVersion: base.osVersion,
			temperatureC: temp,
		},
	});
}

function tz() {
	try {
		return Intl.DateTimeFormat().resolvedOptions().timeZone || null;
	} catch (e) {
		return null;
	}
}

function safeDisplays() {
	try {
		return device.displays() || [];
	} catch (e) {
		return [];
	}
}

module.exports = { collectBasic, collectDeep };
