/**
 * Platform Verification Plan — ref AS/AEGIS-CYBER/VERIFY/2026/001
 * VF-S7 (JIT) — SECOND defect (session-contract mismatch) — STEP-4 POST-FIX
 * DEMONSTRATION (paired controls). Complements (does NOT replace)
 * scripts/vf-s7-jit-postfix-demonstration.ts, which proves the ORIGINAL VF-S7
 * defect fix (tenant-threading + loud-not-silent) at the manager level.
 *
 * THE SECOND DEFECT (caught by the original fix's PROD-confirm): /api/jit/request
 * returned 200 but the durable jit_grants row never landed, because the route read
 * identity from session fields login never sets:
 *   - username     = req.session.username  (unset -> NULL -> username NOT-NULL violation)
 *   - originalRole = req.session.role      (unset -> NULL -> original_role NOT-NULL wall)
 *   - approve.approverRole = req.session.role (unset -> undefined -> approval rejected)
 * The original-defect manager-level harness MISSED this because it passed username/role
 * DIRECTLY to requestAccess — bypassing the route's session read. This harness closes
 * that blind spot: it drives the REAL registered route handlers end-to-end
 * (registerJITAccessRoutes captures them), so the exact production code path
 * (getUser -> username/originalRole -> requestAccess -> persist) is exercised.
 *
 * THE FIX (Option A; architect APPROVED-WITH-FINDINGS):
 *   - request route: actor = await storage.getUser(session.userId);
 *     if (!actor || !actor.isActive) -> 401, no durable write (Finding 1: the
 *     inactive-user guard prevents a deactivated live session from requesting
 *     privilege elevation). username = actor.username; originalRole = actor.role.
 *   - approve route: approverRole = req.effectiveRole (requireRole guarantees it).
 *
 * Legs (Rule 18 — every denial assertion interlocked with a positive in this run):
 *   L1  REQUEST LAND (positive, headline) — real route handler, ACTIVE user, tenant
 *       T_A -> durable jit_grants row LANDS, tenant-correct, and ALL NOT-NULL columns
 *       populated with the user record's REAL values (username/original_role/
 *       elevated_role/reason). This is the path that silently produced username=NULL
 *       in prod; it now lands a complete row.
 *   L2  INACTIVE-USER REFUSED (negative; architect Finding 1) — real route handler,
 *       INACTIVE user -> 401, NO durable row, no counters.
 *   L3  MISSING-USER REFUSED (negative) — real route handler, session.userId with no
 *       user record -> 401, NO durable row.
 *   L4  FAIL-CLOSED default-tenant (negative; re-proven from the original fix) — real
 *       route handler, ACTIVE user, tenant "default" -> route returns 200 success but
 *       durable write DROPPED, persistDroppedNoTenant +1, no row.
 *   L5  APPROVE LAND (positive) — real approve route handler with req.effectiveRole=
 *       'admin' on a pending admin-elevation grant -> approval AUTHORIZED, durable
 *       status pending->active, approved_by recorded. (Pre-fix approverRole=undefined
 *       -> rejected at the approverRoles check.)
 *   L6  APPROVE WRONG-ROLE REFUSED (negative; enforcement control) — approveAccess
 *       with approverRole='auditor' on a pending admin-elevation grant -> REFUSED,
 *       durable status stays 'pending'. Proves approverRole is load-bearing, hence
 *       sourcing it correctly in L5 is a real fix, not cosmetic.
 *
 * Connections:
 *   - owner = pg.Pool on DATABASE_URL (dev owner; bypasses RLS; out-of-band observer
 *     for seeding users + count/column/status + cleanup).
 *   - real path = registered route handlers + jitAccessManager singleton via the
 *     module `db` proxy (appPool = aegis_app restricted role; RLS-enforced) inside a
 *     faithful tenantMiddleware-mirroring request tx (real SAVEPOINT).
 *
 * Run: npx tsx scripts/vf-s7-jit-sessioncontract-demonstration.ts   (DEV only)
 */

import { EventEmitter } from "events";
import pg from "pg";
import { sql } from "drizzle-orm";
import {
  appPool,
  tenantContext,
  makeClientRunner,
  type DrizzleDb,
} from "../server/db";
import {
  registerJITAccessRoutes,
  jitAccessManager,
} from "../server/lib/jit-access";

const owner = new pg.Pool({ connectionString: process.env.DATABASE_URL });

const T_A = "vf-s7-sc-tenant-A";
const PFX = "vf-s7-sc-";
const U_ACTIVE = `${PFX}active`;
const U_INACTIVE = `${PFX}inactive`;
const U_MISSING = `${PFX}missing`; // deliberately NOT seeded
const U_REQR = `${PFX}reqr`; // active requester for L5 pending grant
const U_REQR2 = `${PFX}reqr2`; // active requester for L6 pending grant
const APPROVER = `${PFX}admin-approver`;
const ATTACKER = `${PFX}auditor-attacker`;

const errStr = (e: any) => `${e?.code ?? ""} ${e?.message ?? String(e)}`.trim();

// ---- out-of-band observers (owner pool, bypasses RLS) ----------------------
async function countGrant(id: string): Promise<number> {
  if (!id) return -1;
  const r = await owner.query<{ n: string }>(
    "SELECT count(*)::int AS n FROM jit_grants WHERE id = $1",
    [id],
  );
  return Number(r.rows[0].n);
}
async function grantRow(id: string) {
  const r = await owner.query(
    `SELECT username, original_role, elevated_role, reason, tenant_id, status, approved_by
     FROM jit_grants WHERE id = $1`,
    [id],
  );
  return r.rows[0] ?? null;
}

async function seedUser(id: string, isActive: boolean) {
  // role omitted -> column default 'auditor' (avoids enum-cast on a parameterized
  // text param); realistic: an auditor requesting elevation.
  await owner.query(
    `INSERT INTO users (id, username, password, full_name, is_active)
     VALUES ($1, $2, $3, $4, $5)
     ON CONFLICT (id) DO UPDATE
       SET username = EXCLUDED.username, is_active = EXCLUDED.is_active`,
    [id, `${id}-uname`, "not-a-real-hash", `VF-S7 SC ${id}`, isActive],
  );
}

async function cleanup() {
  await owner.query("DELETE FROM jit_grants WHERE user_id LIKE $1", [`${PFX}%`]);
  await owner.query("DELETE FROM users WHERE id LIKE $1", [`${PFX}%`]);
}

// ---- faithful request runtime — mirrors tenantMiddleware (real SAVEPOINT) ---
interface PhaseDiag {
  commitCommand: string;
  phaseErr: string;
}
async function runRequestPhaseTx(
  tenantId: string,
  fn: (tx: DrizzleDb) => Promise<void>,
): Promise<PhaseDiag> {
  const client = await appPool.connect();
  const diag: PhaseDiag = { commitCommand: "", phaseErr: "" };
  try {
    const tdb = makeClientRunner(client);
    try {
      await tdb.transaction(async (tx) => {
        await tx.execute(
          sql`SELECT set_config('app.current_tenant_id', ${tenantId}, true)`,
        );
        await tenantContext.run(
          { runner: tx as unknown as DrizzleDb, tenantId },
          () => fn(tx as unknown as DrizzleDb),
        );
      });
      diag.commitCommand = "COMMIT";
    } catch (e: any) {
      diag.phaseErr = errStr(e);
      diag.commitCommand = "ROLLBACK";
    }
  } finally {
    client.release();
  }
  return diag;
}

// ---- mock express req/res (drives the REAL captured route handlers) ---------
function makeRes(): any {
  const res: any = new EventEmitter();
  res.statusCode = 200;
  res.writableFinished = false;
  res.body = undefined;
  res.status = (c: number) => {
    res.statusCode = c;
    return res;
  };
  res.json = (b: any) => {
    res.body = b;
    res.writableFinished = true;
    res.emit("finish"); // exercises armRollbackObserver's finish path
    return res;
  };
  return res;
}
function makeReq(opts: {
  userId?: string;
  tenantId?: string;
  effectiveRole?: string;
  body?: any;
  params?: any;
}): any {
  return {
    session: { userId: opts.userId },
    tenantId: opts.tenantId,
    effectiveRole: opts.effectiveRole,
    body: opts.body ?? {},
    params: opts.params ?? {},
  };
}

// ---- capture the REAL route handlers ---------------------------------------
const handlers: Record<string, Function> = {};
const fakeApp = {
  get(path: string, ...a: any[]) {
    handlers[`GET ${path}`] = a[a.length - 1];
  },
  post(path: string, ...a: any[]) {
    handlers[`POST ${path}`] = a[a.length - 1];
  },
};
const requireAuth = (_req: any, _res: any, next?: any) => next?.();
const requireRole = (_role: string) => (_req: any, _res: any, next?: any) =>
  next?.();
registerJITAccessRoutes(fakeApp as any, requireAuth, requireRole);
const requestHandler = handlers["POST /api/jit/request"];
const approveHandler = handlers["POST /api/jit/approve/:id"];

function persistSnapshot() {
  return { ...jitAccessManager.getStats().persistence };
}

interface Row {
  leg: string;
  scenario: string;
  expectation: string;
  observed: string;
  verdict: "PASS" | "FAIL";
}
const rows: Row[] = [];
const record = (r: Row) => rows.push(r);

async function main() {
  console.log(
    "=== VF-S7 JIT SESSION-CONTRACT POST-FIX DEMONSTRATION (route-driven, paired) ===\n",
  );
  if (typeof requestHandler !== "function" || typeof approveHandler !== "function") {
    throw new Error("failed to capture real route handlers");
  }
  await cleanup();
  await seedUser(U_ACTIVE, true);
  await seedUser(U_INACTIVE, false);
  await seedUser(U_REQR, true);
  await seedUser(U_REQR2, true);

  // ---- L1: REQUEST LAND (positive, headline) ------------------------------
  {
    const before = persistSnapshot();
    const reason = "vf-s7-sc L1 request land";
    const res = makeRes();
    const req = makeReq({
      userId: U_ACTIVE,
      tenantId: T_A,
      body: { policyId: "auditor-elevation", reason },
    });
    const diag = await runRequestPhaseTx(T_A, async () => {
      await requestHandler(req, res);
    });
    const after = persistSnapshot();
    const id = res.body?.grant?.id ?? "";
    const cnt = await countGrant(id);
    const r = await grantRow(id);
    const allNotNull =
      !!r &&
      r.username === `${U_ACTIVE}-uname` &&
      r.original_role === "auditor" &&
      r.elevated_role === "auditor" &&
      r.reason === reason &&
      r.tenant_id === T_A &&
      r.status === "active";
    const pass =
      diag.commitCommand === "COMMIT" &&
      res.statusCode === 200 &&
      res.body?.success === true &&
      cnt === 1 &&
      allNotNull &&
      after.persistFailures === before.persistFailures &&
      after.persistRollbacks === before.persistRollbacks &&
      after.persistDroppedNoTenant === before.persistDroppedNoTenant;
    record({
      leg: "L1",
      scenario: "real /api/jit/request handler, ACTIVE user, tenant T_A",
      expectation:
        "200; row LANDS (count=1); ALL NOT-NULL cols populated from user record; tenant=T_A; clean COMMIT; no counters",
      observed: `commit=${diag.commitCommand} http=${res.statusCode} success=${res.body?.success} count=${cnt} username=${r?.username} origRole=${r?.original_role} elevRole=${r?.elevated_role} tenant=${r?.tenant_id} status=${r?.status} failΔ=${after.persistFailures - before.persistFailures}`,
      verdict: pass ? "PASS" : "FAIL",
    });
  }

  // ---- L2: INACTIVE-USER REFUSED (negative; Finding 1) --------------------
  {
    const before = persistSnapshot();
    const res = makeRes();
    const req = makeReq({
      userId: U_INACTIVE,
      tenantId: T_A,
      body: { policyId: "auditor-elevation", reason: "vf-s7-sc L2 inactive" },
    });
    await runRequestPhaseTx(T_A, async () => {
      await requestHandler(req, res);
    });
    const after = persistSnapshot();
    const cnt = await countGrant(res.body?.grant?.id ?? "");
    const userGrants = await owner.query<{ n: string }>(
      "SELECT count(*)::int AS n FROM jit_grants WHERE user_id = $1",
      [U_INACTIVE],
    );
    const pass =
      res.statusCode === 401 &&
      cnt === -1 &&
      Number(userGrants.rows[0].n) === 0 &&
      after.persistFailures === before.persistFailures &&
      after.persistDroppedNoTenant === before.persistDroppedNoTenant;
    record({
      leg: "L2",
      scenario: "real /api/jit/request handler, INACTIVE user (Finding 1)",
      expectation: "401; NO durable row for user; no counters",
      observed: `http=${res.statusCode} userGrants=${userGrants.rows[0].n} failΔ=${after.persistFailures - before.persistFailures}`,
      verdict: pass ? "PASS" : "FAIL",
    });
  }

  // ---- L3: MISSING-USER REFUSED (negative) --------------------------------
  {
    const before = persistSnapshot();
    const res = makeRes();
    const req = makeReq({
      userId: U_MISSING,
      tenantId: T_A,
      body: { policyId: "auditor-elevation", reason: "vf-s7-sc L3 missing" },
    });
    await runRequestPhaseTx(T_A, async () => {
      await requestHandler(req, res);
    });
    const after = persistSnapshot();
    const userGrants = await owner.query<{ n: string }>(
      "SELECT count(*)::int AS n FROM jit_grants WHERE user_id = $1",
      [U_MISSING],
    );
    const pass =
      res.statusCode === 401 &&
      Number(userGrants.rows[0].n) === 0 &&
      after.persistFailures === before.persistFailures;
    record({
      leg: "L3",
      scenario: "real /api/jit/request handler, session.userId with no user record",
      expectation: "401; NO durable row; no counters",
      observed: `http=${res.statusCode} userGrants=${userGrants.rows[0].n} failΔ=${after.persistFailures - before.persistFailures}`,
      verdict: pass ? "PASS" : "FAIL",
    });
  }

  // ---- L4: FAIL-CLOSED default-tenant (negative; re-proven) ---------------
  {
    const before = persistSnapshot();
    const res = makeRes();
    const req = makeReq({
      userId: U_ACTIVE,
      tenantId: "default",
      body: { policyId: "auditor-elevation", reason: "vf-s7-sc L4 fail-closed" },
    });
    await runRequestPhaseTx("default", async () => {
      await requestHandler(req, res);
    });
    const after = persistSnapshot();
    const id = res.body?.grant?.id ?? "";
    const cnt = await countGrant(id);
    const pass =
      res.statusCode === 200 &&
      res.body?.success === true &&
      cnt === 0 &&
      after.persistDroppedNoTenant === before.persistDroppedNoTenant + 1 &&
      after.persistFailures === before.persistFailures;
    record({
      leg: "L4",
      scenario: 'real /api/jit/request handler, ACTIVE user, tenant "default"',
      expectation:
        "200 success (in-memory); NO durable row (count=0); persistDroppedNoTenant +1",
      observed: `http=${res.statusCode} success=${res.body?.success} count=${cnt} dropNoTenantΔ=${after.persistDroppedNoTenant - before.persistDroppedNoTenant}`,
      verdict: pass ? "PASS" : "FAIL",
    });
  }

  // ---- L5: APPROVE LAND (positive) ----------------------------------------
  {
    // (a) requester creates a PENDING admin-elevation grant via the real route
    const reqRes = makeRes();
    const reqReq = makeReq({
      userId: U_REQR,
      tenantId: T_A,
      body: { policyId: "admin-elevation", reason: "vf-s7-sc L5 pending" },
    });
    await runRequestPhaseTx(T_A, async () => {
      await requestHandler(reqReq, reqRes);
    });
    const gid = reqRes.body?.grant?.id ?? "";
    const pendingRow = await grantRow(gid);

    // (b) approve via the real route with effectiveRole='admin'
    const before = persistSnapshot();
    const apRes = makeRes();
    const apReq = makeReq({
      userId: APPROVER,
      tenantId: T_A,
      effectiveRole: "admin",
      params: { id: gid },
    });
    const diag = await runRequestPhaseTx(T_A, async () => {
      await approveHandler(apReq, apRes);
    });
    const after = persistSnapshot();
    const finalRow = await grantRow(gid);
    const pass =
      reqRes.body?.success === true &&
      pendingRow?.status === "pending" &&
      diag.commitCommand === "COMMIT" &&
      apRes.statusCode === 200 &&
      apRes.body?.success === true &&
      finalRow?.status === "active" &&
      finalRow?.approved_by === APPROVER &&
      after.persistFailures === before.persistFailures &&
      after.persistRollbacks === before.persistRollbacks;
    record({
      leg: "L5",
      scenario:
        "real /api/jit/approve handler, effectiveRole='admin', pending admin-elevation grant",
      expectation:
        "request pending->approve AUTHORIZED; durable status pending->active; approved_by set; clean COMMIT",
      observed: `pending=${pendingRow?.status} approveHttp=${apRes.statusCode} success=${apRes.body?.success} finalStatus=${finalRow?.status} approvedBy=${finalRow?.approved_by} failΔ=${after.persistFailures - before.persistFailures}`,
      verdict: pass ? "PASS" : "FAIL",
    });
  }

  // ---- L6: APPROVE WRONG-ROLE REFUSED (negative; enforcement control) -----
  {
    // create a fresh PENDING admin-elevation grant via the real route
    const reqRes = makeRes();
    const reqReq = makeReq({
      userId: U_REQR2,
      tenantId: T_A,
      body: { policyId: "admin-elevation", reason: "vf-s7-sc L6 pending" },
    });
    await runRequestPhaseTx(T_A, async () => {
      await requestHandler(reqReq, reqRes);
    });
    const gid = reqRes.body?.grant?.id ?? "";

    // approverRole='auditor' (non-admin) — proves approverRole is enforced, so
    // sourcing the correct value in L5 is load-bearing, not cosmetic.
    const before = persistSnapshot();
    let result: any;
    await runRequestPhaseTx(T_A, async () => {
      result = await jitAccessManager.approveAccess(gid, ATTACKER, "auditor", {
        tenantId: T_A,
      });
    });
    const after = persistSnapshot();
    const finalRow = await grantRow(gid);
    const pass =
      reqRes.body?.success === true &&
      result?.success === false &&
      result?.error === "Not authorized to approve this request" &&
      finalRow?.status === "pending" &&
      after.persistFailures === before.persistFailures;
    record({
      leg: "L6",
      scenario: "approveAccess with approverRole='auditor' on pending admin-elevation grant",
      expectation:
        "REFUSED (success=false, 'Not authorized...'); durable status stays 'pending'",
      observed: `success=${result?.success} err='${result?.error}' finalStatus=${finalRow?.status} failΔ=${after.persistFailures - before.persistFailures}`,
      verdict: pass ? "PASS" : "FAIL",
    });
  }

  // ---- report ----
  console.log(
    "LEG   VERDICT  SCENARIO / EXPECTATION / OBSERVED\n" +
      "----  -------  ----------------------------------------------------------",
  );
  for (const r of rows) {
    console.log(
      `${r.leg.padEnd(4)}  ${r.verdict.padEnd(7)}  ${r.scenario}\n` +
        `                 expect: ${r.expectation}\n` +
        `                 observe: ${r.observed}\n`,
    );
  }
  const allPass = rows.every((r) => r.verdict === "PASS");
  console.log(
    `\nfinal persistence counters: ${JSON.stringify(persistSnapshot())}`,
  );
  console.log(`\nOVERALL: ${allPass ? "PASS — all legs" : "FAIL — see above"}`);

  await cleanup();
  await owner.end();
  process.exit(allPass ? 0 : 1);
}

main().catch(async (e) => {
  console.error("FATAL", e);
  try {
    await cleanup();
    await owner.end();
  } catch {}
  process.exit(2);
});
