import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { setTimeout as delay } from "node:timers/promises";

const webUrl = process.env.AWP_WEB_URL;
const databaseUrl = process.env.AWP_TEST_POSTGRES_URL;
const playwrightModule = process.env.AWP_PLAYWRIGHT_MODULE;
if (!webUrl) throw new Error("AWP_WEB_URL is required");
if (!databaseUrl) throw new Error("AWP_TEST_POSTGRES_URL is required");
if (!playwrightModule) throw new Error("AWP_PLAYWRIGHT_MODULE is required");

function psql(query: string): string {
  return execFileSync("psql", [databaseUrl!, "-At", "-F", "\t", "-c", query], {
    encoding: "utf8",
  }).trim();
}

const deadline = Date.now() + Number(process.env.AWP_GOLIVE_TIMEOUT_MS ?? "120000");
let row = "";
while (Date.now() < deadline) {
  row = psql(`
    select ar.id, fr.project_id
    from agent_runs ar
    join factory_runs fr on fr.id = ar.factory_run_id
    where (
      select count(*) from attempts a where a.agent_run_id = ar.id
    ) = 2
      and exists (
        select 1
        from attempts retry
        where retry.agent_run_id = ar.id
          and (retry.selection_provenance->>'kind') = 'retry'
          and retry.status in ('running', 'terminal')
      )
    order by ar.created_at desc
    limit 1
  `);
  if (row) break;
  await delay(500);
}
assert.ok(row, "an AgentRun with exactly two immutable Attempts must exist before timeout");
const [agentRunId, projectId] = row.split("\t");
assert.ok(agentRunId);
assert.ok(projectId);

const history = psql(`
  select status || ':' || coalesce(reason, '') || ':' ||
         ((selection_provenance::jsonb)->>'kind') || ':' ||
         coalesce(((selection_provenance::jsonb)->>'previousAttemptId'), '')
  from attempts
  where agent_run_id = '${agentRunId.replaceAll("'", "''")}'
  order by created_at
`).split("\n");
assert.equal(history.length, 2);
assert.match(history[0]!, /^terminal:injected non-zero agent exit 17:initial:/);
assert.match(history[1]!, /^(running|terminal):.*:retry:/);

const { chromium } = await import(playwrightModule);
const browser = await chromium.launch({ headless: true });
try {
  const page = await browser.newPage();
  await page.goto(`${webUrl}/projects/${encodeURIComponent(projectId)}`, {
    waitUntil: "networkidle",
  });
  const run = page.locator(`[data-agent-run-id="${agentRunId}"]`);
  await run.getByText("Attempt 1", { exact: true }).waitFor();
  await run.getByText("Attempt 2", { exact: true }).waitFor();
  await run.getByText("injected non-zero agent exit 17", { exact: true }).first().waitFor();
  await run.getByText("retry", { exact: true }).first().waitFor();
  assert.equal(await run.locator("[data-attempt-id]").count(), 2);
  process.stdout.write(
    `AC-17 PASS: AgentRun ${agentRunId} retains the failed Attempt and rendered retry Attempt with both outcomes\n`,
  );
} finally {
  await browser.close();
}
