#!/usr/bin/env node
/**
 * Validate OTA sync manifest + local diff simulation (Linux CI / dev).
 */
import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const ROOT = path.resolve(__dirname, '..');
const MANIFEST = path.resolve(
  ROOT,
  '../siraya-pos/frontend/public/downloads/printer/channels/dev/manifest.json',
);
const SYNC_ROOT = path.resolve(
  ROOT,
  '../siraya-pos/frontend/public/downloads/printer/sync/win-x64',
);

function fail(msg) {
  console.error(`FAIL: ${msg}`);
  process.exit(1);
}

function sha256File(p) {
  return crypto.createHash('sha256').update(fs.readFileSync(p)).digest('hex');
}

if (!fs.existsSync(MANIFEST)) fail(`missing manifest ${MANIFEST}`);
const manifest = JSON.parse(fs.readFileSync(MANIFEST, 'utf8'));
if (!manifest.version) fail('manifest.version missing');
if (!manifest.baseUrl) fail('manifest.baseUrl missing');
if (!Array.isArray(manifest.files) || manifest.files.length === 0)
  fail('manifest.files empty');

let missing = 0;
for (const f of manifest.files) {
  const local = path.join(SYNC_ROOT, f.path);
  if (!fs.existsSync(local)) {
    console.error(`missing sync file: ${f.path}`);
    missing++;
    continue;
  }
  const hash = sha256File(local);
  if (hash !== f.sha256) {
    console.error(`hash mismatch: ${f.path}`);
    missing++;
  }
}
if (missing) fail(`${missing} manifest file(s) invalid`);

const required = [
  'app/index.js',
  'app/installer/windows/install-from-folder.ps1',
  'runtime/node.exe',
];
for (const rel of required) {
  if (!manifest.files.some((f) => f.path === rel)) fail(`required entry missing: ${rel}`);
}

console.log(`OK manifest v${manifest.version} — ${manifest.files.length} files verified`);
console.log(`  ${MANIFEST}`);
