/* SPDX-License-Identifier: AGPL-3.0-only
   SPDX-FileCopyrightText: 2026 Com'Together */
/* Runner EN LIGNE DE COMMANDE des tests du moteur français.
   Utilise EXACTEMENT les mêmes fichiers que tests/run.html (aucune copie du corpus).
   Nécessite un runtime JS (Node/Deno/Bun). Sur une machine sans Node, utiliser tests/run.html.

   Usage :  node tests/run-grammar-tests.js
   Sortie :  code 0 si conforme (aucune régression, aucune propriété violée),
             code 1 sinon. Les LIMITATIONS connues n'échouent jamais. */
"use strict";
// Shim : les fichiers de test posent window.X ; on fait pointer window vers l'objet global.
globalThis.window = globalThis;
const path = require("path");
require(path.join(__dirname, "..", "grammar.js"));
require(path.join(__dirname, "..", "sentence.js"));
require(path.join(__dirname, "corpus-grammaire.js"));
require(path.join(__dirname, "corpus-phrase.js"));
require(path.join(__dirname, "proprietes.js"));
require(path.join(__dirname, "harness.js"));

const r = window.runAll();
const line = "─".repeat(52);
if (r.error) { console.error("❌ " + r.error); process.exit(1); }

console.log(line);
console.log("  Com'Together — tests du moteur de français");
console.log(line);
const s = r.sentence || { total: 0, passed: 0, regressions: [], limitations: [] };
const totalLimits = r.limitations.length + s.limitations.length;
console.log(`  Contrats conjugaison   : ${r.contracts.passed}/${r.contracts.total} réussis`);
console.log(`  Contrats phrase        : ${s.passed}/${s.total} réussis`);
console.log(`  Propriétés générales   : ${r.properties.checks} combinaisons, ${r.properties.propertiesFailed} propriété(s) violée(s)`);
console.log(`  Limitations connues    : ${totalLimits} (${r.resolvedCount} résolue(s) à promouvoir, ${r.driftedCount} à revoir)`);
console.log(`  Régressions            : ${r.contracts.regressions.length + s.regressions.length}`);
console.log(line);

if (r.contracts.regressions.length) {
  console.log("\n❌ RÉGRESSIONS (conjugaison) :");
  r.contracts.regressions.forEach(x => console.log(`   ✗ ${x.v}/${x.s}/${x.t} : attendu « ${x.expect} », obtenu « ${x.got} »  [${x.rule}]`));
}
if (s.regressions.length) {
  console.log("\n❌ RÉGRESSIONS (phrase) :");
  s.regressions.forEach(x => console.log(`   ✗ ${x.tokens.map(t => t.label).join(" + ")} : attendu « ${x.expect} », obtenu « ${x.got} »  [${x.rule}]`));
}
if (r.properties.failures.length) {
  console.log("\n❌ PROPRIÉTÉS VIOLÉES :");
  r.properties.failures.forEach(f => console.log(`   ✗ ${f.property}  (ex. ${f.example})`));
}
const allLimits = r.limitations.concat(s.limitations);
if (allLimits.length) {
  console.log("\n⚠️  LIMITATIONS CONNUES (non bloquantes) :");
  allLimits.forEach(l => {
    const entry = l.tokens ? l.tokens.map(t => t.label).join(" + ") : (l.v + "/" + l.t);
    if (l.resolved) console.log(`   ✅ ${l.issue} RÉSOLUE — ${entry} produit « ${l.got} ». À promouvoir en contrat.`);
    else if (l.drifted) console.log(`   ⁇ ${l.issue} À REVOIR — ${entry} : obtenu « ${l.got} » (ni « ${l.current} » ni la cible « ${l.expectedEventually} »).`);
    else console.log(`   ⚠️ ${l.issue} — ${entry} : « ${l.got} », attendu à terme « ${l.expectedEventually} ». ${l.rule}`);
  });
}
console.log("\n" + (r.ok ? "✅ CONFORME — publication autorisée." : "❌ NON CONFORME — publication à bloquer."));
process.exit(r.ok ? 0 : 1);
