// PRUEBA DEL AVISADOR DE VERSIONES (2026-07-30)
// La Estacion NO se actualiza sola (arts. 9-11 de la 000121): el canal solo
// AVISA. Se prueba que detecta lo mas nuevo, que ignora lo rezagado y lo
// invalido, y que aplicar en desarrollo rebota con su mensaje.
import { createServer } from 'node:http';
import { mkdtempSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';

let fallos = 0;
const check = (cond, msg) => {
  console.log((cond ? '  OK  ' : '  XX  ') + msg);
  if (!cond) fallos++;
};

// El servidor de mentira que hace de canal publicado.
let respuesta = {};
const canal = createServer((req, res) => {
  res.writeHead(200, { 'content-type': 'application/json' });
  res.end(JSON.stringify(respuesta));
});
await new Promise((listo) => canal.listen(8752, '127.0.0.1', listo));

// La version de "esta instalacion" y el canal se fijan ANTES de importar.
process.env.FISCAL_VERSION = '1.0.0';
process.env.EF_URL_VERSION = 'http://127.0.0.1:8752/version.json';
const { crearAvisador, esMasNueva, VERSION_ESTACION } = await import('../dist/actualizador.js');

const dir = mkdtempSync(join(tmpdir(), 'fiscal-avi-'));
try {
  console.log('\n== 1. Comparar versiones sin enredos ==');
  check(esMasNueva('1.0.1', '1.0.0'), '1.0.1 es mas nueva que 1.0.0');
  check(esMasNueva('1.10.0', '1.9.9'), '1.10.0 gana a 1.9.9 (numero a numero, no texto)');
  check(!esMasNueva('0.9.9', '1.0.0'), 'un canal rezagado jamas propone volver atras');
  check(!esMasNueva('1.0.0', '1.0.0'), 'la misma version no avisa');
  check(!esMasNueva('2.0.0', 'dev'), 'una instalacion de desarrollo no recibe avisos');
  check(!esMasNueva('basura', '1.0.0'), 'una version invalida del canal se ignora');
  check(VERSION_ESTACION === '1.0.0', `la version de la instalacion quedo fijada (${VERSION_ESTACION})`);

  console.log('\n== 2. El canal avisa lo mas nuevo y solo lo mas nuevo ==');
  const avisador = crearAvisador({ base: dir, esExe: false, log: () => {} });
  respuesta = { version: '1.0.1', url: 'http://127.0.0.1:8752/Estacion-Fiscal-1.0.1.exe' };
  await avisador.verificar();
  check(avisador.estado().disponible === '1.0.1', 'detecta la version nueva');
  check(avisador.estado().actual === '1.0.0', 'y dice cual tiene la instalacion');

  respuesta = { version: '0.9.0', url: 'http://127.0.0.1:8752/vieja.exe' };
  await avisador.verificar();
  check(avisador.estado().disponible === null, 'un canal rezagado apaga el aviso, no propone downgrade');

  respuesta = { cualquier: 'cosa' };
  await avisador.verificar();
  check(avisador.estado().disponible === null, 'un canal invalido no rompe nada');

  console.log('\n== 3. Aplicar es decision aparte, y en desarrollo rebota ==');
  respuesta = { version: '1.0.1', url: 'http://127.0.0.1:8752/Estacion-Fiscal-1.0.1.exe' };
  await avisador.verificar();
  check(avisador.estado().disponible === '1.0.1', 'el aviso esta puesto');
  const err = await avisador.aplicar();
  check(/programa instalado/i.test(err ?? ''), 'aplicar fuera del exe instalado rebota con su porque');
  check(avisador.estado().disponible === '1.0.1', 'y el aviso sigue ahi: nada se aplico solo');
  avisador.detener();
} catch (e) {
  console.log('  XX  ' + e.message);
  fallos++;
} finally {
  canal.close();
  rmSync(dir, { recursive: true, force: true });
}

console.log(fallos === 0 ? '\nAVISADOR DE VERSIONES: TODO VERDE' : `\n${fallos} FALLO(S)`);
// Salida natural, sin process.exit(): en Node 24 sobre Windows, forzar la
// salida mientras undici cierra sus conexiones revienta con la asercion de
// libuv UV_HANDLE_CLOSING y tumba la cadena de pruebas aunque todo este verde.
process.exitCode = fallos === 0 ? 0 : 1;
