/**
 * AEGIS SOAR — prod-topology-smoke (AS/PLATFORM/2026/002 §4, §5.1).
 *
 * Confirms a deploy reads the RIGHT database (prod neondb ≠ dev heliumdb) and
 * captures the absent→present fresh-marker discriminator (a table/constraint that
 * flips absent→present, or a route 404→200/401 flip) proving the FRESH bundle/schema
 * is actually live — not a stale artefact reporting a false green.
 *
 * Usage:
 *   npx tsx scripts/prod-topology-smoke.ts --expect <dbname> \
 *     [--present-table <t> ...] [--absent-table <t> ...]
 *     [--present-constraint <table:conname> ...] [--absent-constraint <table:conname> ...]
 *
 *   --expect <dbname>          assert current_database() equals this (heliumdb dev / neondb prod)
 *   --present-table <t>        marker that MUST be present (post-deploy live check)
 *   --absent-table <t>         marker that MUST be absent  (pre-deploy / fence check)
 *   --present-constraint a:b   constraint b on table a MUST be present
 *   --absent-constraint  a:b   constraint b on table a MUST be absent
 *
 * Target DB resolution: TARGET_DATABASE_URL ?? DATABASE_URL (string never printed, Rule 1).
 * HOLD: this is the dev mechanism check; a LIVE prod run is deferred to the M3 gate
 * (Rule 19 — verified-in-dev, not-prod-re-run).
 *
 * Exit codes: 0 = topology + all markers satisfied; 1 = mismatch; 2 = usage.
 */
import { openTargetPool, currentDatabase, tableExists, constraintExists } from "./lib/schema-probe";

function multi(argv: string[], flag: string): string[] {
  const out: string[] = [];
  for (let i = 0; i < argv.length; i++) if (argv[i] === flag && argv[i + 1]) out.push(argv[i + 1]);
  return out;
}
function single(argv: string[], flag: string): string | undefined {
  const i = argv.indexOf(flag);
  return i >= 0 ? argv[i + 1] : undefined;
}

async function main(): Promise<void> {
  const argv = process.argv.slice(2);
  const expect = single(argv, "--expect");
  const presentTables = multi(argv, "--present-table");
  const absentTables = multi(argv, "--absent-table");
  const presentCons = multi(argv, "--present-constraint");
  const absentCons = multi(argv, "--absent-constraint");

  const pool = openTargetPool();
  const failures: string[] = [];
  try {
    const db = await currentDatabase(pool);
    console.log("=".repeat(82));
    console.log("prod-topology-smoke");
    console.log("-".repeat(82));
    console.log(`current_database = ${db}`);
    if (expect) {
      const ok = db === expect;
      console.log(`  ${ok ? "OK  " : "FAIL"} expected database = ${expect}`);
      if (!ok) failures.push(`current_database ${db} != expected ${expect}`);
    } else {
      console.log("  (no --expect; database name reported only)");
    }

    for (const t of presentTables) {
      const ok = await tableExists(pool, t);
      console.log(`  ${ok ? "OK  " : "FAIL"} present-table ${t} = ${ok ? "present" : "ABSENT"}`);
      if (!ok) failures.push(`present-table ${t} absent`);
    }
    for (const t of absentTables) {
      const ex = await tableExists(pool, t);
      console.log(`  ${!ex ? "OK  " : "FAIL"} absent-table ${t} = ${ex ? "PRESENT" : "absent"}`);
      if (ex) failures.push(`absent-table ${t} present`);
    }
    for (const spec of presentCons) {
      const [t, c] = spec.split(":");
      const ok = await constraintExists(pool, t, c);
      console.log(`  ${ok ? "OK  " : "FAIL"} present-constraint ${t}.${c} = ${ok ? "present" : "ABSENT"}`);
      if (!ok) failures.push(`present-constraint ${spec} absent`);
    }
    for (const spec of absentCons) {
      const [t, c] = spec.split(":");
      const ex = await constraintExists(pool, t, c);
      console.log(`  ${!ex ? "OK  " : "FAIL"} absent-constraint ${t}.${c} = ${ex ? "PRESENT" : "absent"}`);
      if (ex) failures.push(`absent-constraint ${spec} present`);
    }
  } finally {
    await pool.end();
  }

  console.log("=".repeat(82));
  if (failures.length === 0) {
    console.log("TOPOLOGY-SMOKE: PASS");
    process.exit(0);
  }
  console.log(`TOPOLOGY-SMOKE: FAIL — ${failures.length} issue(s):`);
  for (const f of failures) console.log(`  - ${f}`);
  process.exit(1);
}

main().catch((e) => { console.error("topology-smoke crashed:", e?.message ?? e); process.exit(2); });
