/**
 * # status page renderer — the capability catalog as a byte-deterministic public page (kestrel-gsh.2)
 *
 * `renderStatusPage` is a **pure function** of the catalog + the extracted public fences: same inputs
 * ⇒ byte-identical Markdown, with stable ordering and no wall clock, so the committed page
 * (`docs/public/status.md`) can never drift from the catalog (a CI test re-renders and compares
 * byte-for-byte). The page is framework-neutral plain Markdown — tables and inline code only, no
 * executable fences — so it adds no managed fences to the gsh.1 corpus and needs no site shell.
 *
 * The four axes render as four independent columns; the certified cohort banner states the honest
 * count (0) up front so no reader mistakes a mechanical run for a certified one.
 */

import type { Capability, EvidenceTier, RuntimeStatus, SyntaxStatus } from "./catalog.ts";
import { CAPABILITIES, CERTIFIED_COHORT, EVIDENCE_SOURCE, validateCatalog } from "./catalog.ts";
import type { ManagedFence } from "./fences.ts";
import { collectManagedFences } from "./fences.ts";

/** The label the generator writes into `docs/public/status.md`'s "regenerate with" line. */
export const REGEN_COMMAND = "bun scripts/gen-status.ts";

const SYNTAX_LABEL: Record<SyntaxStatus, string> = {
  supported: "supported",
  proposed: "proposed",
  rejected: "rejected (fail-closed)",
};
const RUNTIME_LABEL: Record<RuntimeStatus, string> = {
  implemented: "implemented",
  partial: "partial",
  none: "none",
};
const EVIDENCE_LABEL: Record<EvidenceTier, string> = {
  none: "none",
  mechanical: "mechanical (practice)",
  certified: "certified",
};

const SURFACE_ORDER = ["text", "sdk", "cli", "mcp", "adapter"] as const;

/** Escape a cell for a GitHub-flavored Markdown table (only `|` needs escaping in our content). */
const cell = (s: string): string => s.replace(/\|/g, "\\|");

function accessCell(c: Capability): string {
  const parts: string[] = [];
  for (const surface of SURFACE_ORDER) {
    const level = c.access.surfaces[surface];
    if (level !== undefined) parts.push(`${surface}: ${level}`);
  }
  return parts.length === 0 ? "—" : parts.join(", ");
}

/** Render the whole status page. Pure: deterministic in `capabilities` + `managed` only. */
export function renderStatusPage(
  capabilities: readonly Capability[] = CAPABILITIES,
  managed: readonly ManagedFence[] = collectManagedFences().managed,
): string {
  const sorted = [...capabilities].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
  const { orphanExamples, orphanCapabilities } = validateCatalog(capabilities, managed);

  // fence id -> the capability ids that claim it (sorted), for the example→capability resolution table.
  const byFence = new Map<string, string[]>();
  for (const c of sorted) for (const ex of c.examples) {
    const list = byFence.get(ex) ?? [];
    list.push(c.id);
    byFence.set(ex, list);
  }

  const out: string[] = [];
  const L = (line = ""): void => void out.push(line);

  L("<!-- GENERATED FILE — do not edit by hand.");
  L(`     Regenerate from the typed capability catalog with: ${REGEN_COMMAND}`);
  L("     Source of truth: tests/support/catalog.ts · renderer: tests/support/status.ts");
  L("     A CI test (tests/docs.catalog.test.ts) asserts this file equals a fresh regeneration. -->");
  L();
  L("# Kestrel capability status");
  L();
  L(
    "This page is generated from the typed capability catalog (`tests/support/catalog.ts`). Every row " +
      "is graded independently on **four axes** — a feature can *parse* yet have no *runtime*, no graded " +
      "*evidence*, and only partial *access*. A single \"supported\" flag would collapse those into one " +
      "flattering lie; the catalog forbids that, and every public claim below cites a source (`src/`) and " +
      "a test (`tests/`) receipt.",
  );
  L();
  L("- **Syntax** — does the grammar (`src/lang`) accept it? `supported` · `proposed` · `rejected`.");
  L("- **Runtime** — is the executable behavior implemented? `implemented` · `partial` · `none`.");
  L("- **Evidence** — accumulated *graded trading* evidence (never unit tests) and its tier: `none` · `mechanical (practice)` · `certified`.");
  L("- **Access** — which entry surfaces reach it: text DSL · TS SDK · CLI · MCP · adapters.");
  L();
  L(
    `> **Certified honest-tier cohort: ${CERTIFIED_COHORT}.** Per kestrel-pqv.1, the agent-day evidence in ` +
      `[\`${EVIDENCE_SOURCE}\`](${relativeFromPublic(EVIDENCE_SOURCE)}) is **practice tier** — its author boundary ` +
      `leaked calendar identity and the contamination fence is conjunctive, so no run is certified. Any row below ` +
      `marked \`mechanical (practice)\` is a mechanically-graded practice run, never a certified result.`,
  );
  L();

  // ── Axis table ────────────────────────────────────────────────────────────────
  L("## Capabilities");
  L();
  L("| Capability | Syntax | Runtime | Evidence | Access |");
  L("| --- | --- | --- | --- | --- |");
  for (const c of sorted) {
    L(
      `| ${cell(c.title)} (\`${c.id}\`) | ${cell(SYNTAX_LABEL[c.syntax.status])} | ${cell(RUNTIME_LABEL[c.runtime.status])} | ${cell(EVIDENCE_LABEL[c.evidence.tier])} | ${cell(accessCell(c))} |`,
    );
  }
  L();

  // ── Per-capability detail (summary, notes, receipts, examples) ─────────────────
  L("## Detail & receipts");
  L();
  for (const c of sorted) {
    L(`### ${c.title} \`${c.id}\``);
    L();
    L(cell(c.summary));
    L();
    L(`- **Syntax:** ${SYNTAX_LABEL[c.syntax.status]}${c.syntax.note ? ` — ${c.syntax.note}` : ""}`);
    L(`- **Runtime:** ${RUNTIME_LABEL[c.runtime.status]}${c.runtime.note ? ` — ${c.runtime.note}` : ""}`);
    L(`- **Evidence:** ${EVIDENCE_LABEL[c.evidence.tier]}${c.evidence.note ? ` — ${c.evidence.note}` : ""}`);
    L(`- **Access:** ${accessCell(c)}${c.access.note ? ` — ${c.access.note}` : ""}`);
    const src = [...c.receipts.source].sort().map((p) => `\`${p}\``).join(", ") || "—";
    const tst = [...c.receipts.test].sort().map((p) => `\`${p}\``).join(", ") || "—";
    L(`- **Source receipts:** ${src}`);
    L(`- **Test receipts:** ${tst}`);
    const exs = [...c.examples].sort().map((e) => `\`${e}\``).join(", ") || "—";
    L(`- **Public examples:** ${exs}`);
    L();
  }

  // ── Example → capability resolution ────────────────────────────────────────────
  L("## Public examples resolved to capabilities");
  L();
  L(
    "Every Kestrel fence shipped in `README.md` and `docs/public/**` (extracted by the gsh.1 checker) " +
      "resolves to at least one catalogued capability. An orphan example fails CI.",
  );
  L();
  L("| Example fence | Role | Source | Capabilities |");
  L("| --- | --- | --- | --- |");
  const fences = [...managed].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
  for (const f of fences) {
    const caps = (byFence.get(f.id) ?? []).map((id) => `\`${id}\``).join(", ") || "**(orphan — none)**";
    L(`| \`${f.id}\` | ${f.role} | ${cell(`${f.file}:${f.startLine}`)} | ${caps} |`);
  }
  L();

  // ── Coverage integrity ─────────────────────────────────────────────────────────
  L("## Coverage integrity");
  L();
  L(`- **Orphan examples** (public fence resolving to no capability): ${orphanExamples.length === 0 ? "none" : orphanExamples.map((id) => `\`${id}\``).join(", ")}`);
  L(`- **Orphan capabilities** (catalogued but with no public example): ${orphanCapabilities.length === 0 ? "none" : orphanCapabilities.map((id) => `\`${id}\``).join(", ")}`);
  L();

  return out.join("\n") + "\n";
}

/** docs/public/status.md → a link back to a repo path (e.g. docs/results/…) is `../results/…`. */
function relativeFromPublic(repoPath: string): string {
  return "../" + repoPath.replace(/^docs\//, "");
}
