/* SPDX-FileCopyrightText: 2026 Com'Together
   SPDX-License-Identifier: AGPL-3.0-only
   Verrou du mapper jsRealB (syntaxe avancée opt-in). Charge le MÊME bundle jsRealB que l'appli
   (assets/jsrealb/jsRealB.js) + le module pur lang/jsr-map.js, puis vérifie le corpus-or.
   null attendu = motif hors couverture => l'appli fait un repli sur le moteur linéaire. */
const path = require("path");
const ROOT = path.join(__dirname, "..");
const jsr = require(path.join(ROOT, "assets", "jsrealb", "jsRealB.js"));
jsr.loadFr();
const { mapTokens } = require(path.join(ROOT, "lang", "jsr-map.js"));

// Fabriques de jetons (mêmes propriétés que dans l'appli).
const P = l => ({ label: l });                                  // pronom sujet (label seul)
const V = inf => ({ label: inf, verb: inf });                   // verbe : `verb` = infinitif
const C = (l, o = {}) => Object.assign({ label: l }, o);        // clitique objet (le/la/les/lui/leur), fem/plural éventuels
const NEG = l => ({ label: l, color: "negation" });

const CAS = [
  // — motif couvert : clitiques (ordre correct, ce que le moteur linéaire ne sait pas) —
  { t: "je+donner+le+lui", toks: [P("je"), V("donner"), C("le"), C("lui")], ctx: {}, exp: "je le lui donne" },
  { t: "elle+voir+les [présent]", toks: [P("elle"), V("voir"), C("les")], ctx: {}, exp: "elle les voit" },
  { t: "je+voir+la (fém. par libellé)", toks: [P("je"), V("voir"), C("la")], ctx: {}, exp: "je la vois" },
  { t: "je+voir+les (plur. par libellé)", toks: [P("je"), V("voir"), C("les")], ctx: {}, exp: "je les vois" },
  { t: "je+donner+leur (dat. plur.)", toks: [P("je"), V("donner"), C("leur")], ctx: {}, exp: "je leur donne" },
  { t: "nous+donner+le+lui", toks: [P("nous"), V("donner"), C("le"), C("lui")], ctx: {}, exp: "nous le lui donnons" },
  // — négation « ne…pas » portée (bug corrigé : ne tombe plus dans l'affirmatif) —
  { t: "je+NEG+donner+le+lui [écrit]", toks: [P("je"), NEG("ne pas"), V("donner"), C("le"), C("lui")], ctx: { registre: "ecrit" }, exp: "je ne le lui donne pas" },
  { t: "je+NEG+donner+le+lui [oral]", toks: [P("je"), NEG("ne pas"), V("donner"), C("le"), C("lui")], ctx: { registre: "oral" }, exp: "je le lui donne pas" },
  // — temps —
  { t: "je+donner+le+lui [futur]", toks: [P("je"), V("donner"), C("le"), C("lui")], ctx: { tense: "futursimple" }, exp: "je le lui donnerai" },
  // — REPLI attendu (null) : hors motif, l'appli utilise le moteur linéaire —
  { t: "sans clitique -> repli", toks: [P("je"), V("vouloir"), V("partir")], ctx: {}, exp: null },
  { t: "négation forte 'jamais' -> repli", toks: [P("je"), NEG("jamais"), V("donner"), C("le"), C("lui")], ctx: {}, exp: null },
  { t: "verbe gouverné (2 verbes) -> repli", toks: [P("je"), V("vouloir"), C("le"), V("donner")], ctx: {}, exp: null },
  { t: "sujet non pronom -> repli", toks: [C("le"), V("donner"), C("lui")], ctx: {}, exp: null },
];

let pass = 0, fail = 0;
console.log("── Verrou mapper jsRealB (corpus-or) ──");
for (const c of CAS) {
  const got = mapTokens(jsr, c.toks, c.ctx);
  const ok = got === c.exp;
  ok ? pass++ : fail++;
  const show = v => v === null ? "null (repli)" : "« " + v + " »";
  console.log(`  ${ok ? "✓" : "✗"} ${c.t.padEnd(38)} -> ${show(got)}${ok ? "" : "   ATTENDU " + show(c.exp)}`);
}
console.log(`\n${fail === 0 ? "✅" : "❌"} Mapper jsRealB : ${pass}/${CAS.length} conforme${fail ? " (" + fail + " échec)" : ""}.`);
process.exit(fail === 0 ? 0 : 1);
