import { execFileSync } from "node:child_process";
import { readFileSync, writeFileSync, renameSync, mkdirSync } from "node:fs";
import { join } from "node:path";
import { expect } from "e2e";
import { APP_DIR, T3_HOME } from "../e2e.config.ts";
import { test, WEB } from "./t3.ts";

test("Git failures are errors while absent repositories remain missing", WEB, async ({ t3, app, screen }) => {
  const sha = execFileSync("git", ["rev-parse", "HEAD"], { cwd: APP_DIR, encoding: "utf8" }).trim();
  const out = join(process.env.T3_EVIDENCE_DIR!, `${sha}-${Date.now()}`);
  const logStart = readFileSync(new URL("../.e2e/app.log", import.meta.url), "utf8").length;
  mkdirSync(out, { recursive: true });
  const results: Record<string, unknown> = {};
  const statuses: Record<string, string[]> = {};
  for (const kind of ["broken", "plain", "healthy"]) {
    const project = await t3.project(`${kind}-repository`, { "README.md": "Synthetic checkpoint reproduction\n" });
    if (kind === "broken") writeFileSync(join(project, ".git/config"), "invalid config\n");
    if (kind === "plain") renameSync(join(project, ".git"), join(project, "git-disabled"));
    await t3.thread({ project, title: `${kind} Git checkpoint proof`, model: "todo-list", messages: ["Create a todo list"] });
    const rows = JSON.parse(execFileSync("sqlite3", ["-readonly", "-json", join(T3_HOME, "userdata/statev2.sqlite"), `SELECT c.ordinal_within_scope AS ordinal,c.status,json_extract(c.payload_json,'$.files') AS files FROM orchestration_v2_projection_checkpoints c JOIN orchestration_v2_projection_threads t ON t.thread_id=c.thread_id WHERE t.title='${kind} Git checkpoint proof' ORDER BY c.ordinal_within_scope`], { encoding: "utf8" }));
    results[kind] = rows;
    statuses[kind] = rows.map((row: {status: string}) => row.status);
  }
  // Only synthetic diagnostics are retained; workspace paths and provider metadata stay private.
  const log = readFileSync(new URL("../.e2e/app.log", import.meta.url), "utf8").slice(logStart);
  const warnings = log.split("\n").filter(line => /checkpoint repository probe failed|bad config line|invalid config/.test(line)).map(line => line.replaceAll(T3_HOME, "<scenario-home>").replace(/\/home\/[^\s\"',)]+/g, "<workspace>"));
  writeFileSync(join(out, "runtime.json"), JSON.stringify({ sha, steps: "Valid project registration; corrupt .git/config; replay todo-list turn; inspect persisted checkpoints. Repeat plain and healthy controls.", checkpoints: results, probeWarningCount: (log.match(/checkpoint repository probe failed/g) ?? []).length, diagnostics: warnings }, null, 2));
  await t3.open();
  await screen.getByRole("button", "broken Git checkpoint proof, Done, broken-repository").tap();
  await screen.getByText("todo list fixture complete", { exact: true }).waitFor();
  await screen.getByText("Syncing messages...", { exact: true }).waitFor({ state: "hidden" });
  await app.screenshot("completed-broken-repository-turn");
  console.log(JSON.stringify({ sha, checkpoints: results, probeWarningCount: (log.match(/checkpoint repository probe failed/g) ?? []).length }));
  await expect(statuses.broken).toEqual(["error", "error"]);
  await expect(statuses.plain).toEqual(["missing", "missing"]);
  await expect(statuses.healthy).toEqual(["ready", "ready"]);
  await expect(warnings.length > 0).toEqual(true);
});
