#!/usr/bin/env node
/**
 * CLI for the §B/§C1 mechanical binding-gate.
 *
 *   node --import tsx src/cli.ts <utkast.md> [--json]
 *
 * Exit code: 0 if the gate passes (no BLOCK violations — handoff permitted),
 * 1 if BLOCKED, 2 on usage error. WARN violations never fail the gate; they are
 * surfaced for KTG's judgment. The text output is the "kvittering" the writing
 * contract asks for when a draft is delivered.
 */

import { runGateFile } from "./gate.js";
import { ratifyFile, defaultContractPath } from "./ratify.js";
import type { RatifyResult } from "./ratify.js";
import type { GateResult, Violation } from "./types.js";

function printViolation(v: Violation): void {
  console.log(`  [${v.ref}] ${v.ruleId}`);
  if (v.observed !== undefined) {
    const t = v.threshold !== undefined ? ` (terskel: ${v.threshold})` : "";
    console.log(`    observert: ${v.observed}${t}`);
  }
  console.log(`    → ${v.message}`);
  const shown = v.matches.slice(0, 5);
  for (const m of shown) console.log(`    · L${m.line}: ${m.excerpt}`);
  if (v.matches.length > shown.length) {
    console.log(`    · … +${v.matches.length - shown.length} til`);
  }
}

function report(r: GateResult): void {
  console.log("§B/§C1 regelsjekk-gate");
  console.log(`Utkast: ${r.draftPath ?? "(stdin)"}  ·  ${r.wordCount} ord\n`);
  if (r.blocks.length) {
    console.log(`BLOCK (${r.blocks.length}) — må fikses før handoff:`);
    r.blocks.forEach(printViolation);
    console.log("");
  }
  if (r.warns.length) {
    console.log(`WARN (${r.warns.length}) — krever din dom (blokkerer ikke):`);
    r.warns.forEach(printViolation);
    console.log("");
  }
  if (r.passed) {
    console.log(`✓ Gate passert — 0 block, ${r.warns.length} warn til vurdering.`);
  } else {
    console.log(
      `✗ BLOKKERT — ${r.blocks.length} block, ${r.warns.length} warn. Fiks block-ene og kjør på nytt.`,
    );
  }
}

function reportRatify(r: RatifyResult): void {
  console.log("Gate-bindings-ratify (rules.ts ↔ §E-manifest)");
  console.log(
    `Kontrakt: ${r.contractPath ?? "(ukjent)"}  ·  ${r.ruleCount} regler / ${r.manifestCount} manifest-rader\n`,
  );
  if (r.issues.length) {
    console.log(`DRIFT (${r.issues.length}):`);
    for (const i of r.issues) console.log(`  [${i.kind}] ${i.id}\n    → ${i.detail}`);
    console.log("");
    console.log("✗ Ute av sync — rules.ts og §E-manifestet stemmer ikke. Rett før promotering teller.");
  } else {
    console.log(`✓ I sync — ${r.ruleCount} regler bundet 1:1 til §E-manifestet (ref + severity stemmer).`);
  }
}

function runRatify(args: string[], jsonOut: boolean): never {
  const argPath = args.find((a) => !a.startsWith("--"));
  const path = argPath ?? process.env.MASKINROMMET_CONTRACT ?? defaultContractPath();
  const result = ratifyFile(path);
  if (jsonOut) console.log(JSON.stringify(result, null, 2));
  else reportRatify(result);
  process.exit(result.ok ? 0 : 1);
}

function main(): void {
  const args = process.argv.slice(2);
  const jsonOut = args.includes("--json");
  if (args.includes("--ratify")) {
    runRatify(args, jsonOut);
  }
  const path = args.find((a) => !a.startsWith("--"));
  if (!path) {
    console.error("Bruk: contract-gate <utkast.md> [--json]  |  contract-gate --ratify [kontrakt.md] [--json]");
    process.exit(2);
  }
  const result = runGateFile(path);
  if (jsonOut) console.log(JSON.stringify(result, null, 2));
  else report(result);
  process.exit(result.passed ? 0 : 1);
}

main();
