import { rmSync } from "node:fs";
import { expect, test } from "bun:test";

import { runAgentRunCommand } from "./agentrun";

const RUN_ID = "run_reuse_summary_fixture";

test("AgentRun reuse summary paginates all events and reports one runner across turns", async () => {
  const commandIds = Array.from({ length: 5 }, (_, index) => `cmd_${index + 1}`);
  const events: Array<Record<string, unknown>> = [];
  let seq = 1;
  const append = (type: string, payload: Record<string, unknown>): void => {
    events.push({ id: `evt_${seq}`, seq, type, payload });
    seq += 1;
  };
  for (let index = 0; index < 485; index += 1) append("backend_status", { phase: `noise-${index}` });
  append("backend_status", { phase: "runner-job-created", commandId: commandIds[0], runnerJobId: "rjob_one", runnerId: "runner_one", jobName: "runner-job-one" });
  append("backend_status", { phase: "runner-source-fetch-started", commandId: commandIds[0] });
  append("backend_status", { phase: "resource-bundle-materialized", commandId: commandIds[0] });
  for (const [index, commandId] of commandIds.entries()) {
    append("backend_status", { phase: "command-created", commandId });
    if (index > 0) {
      append("backend_status", { phase: "codex-app-server:reused", commandId });
      append("backend_status", { phase: "thread/resume:completed", commandId });
    }
    append("backend_status", { phase: "backend-turn-started", commandId });
    append("backend_status", { phase: "command-terminal", commandId, terminalStatus: "completed" });
    append("terminal_status", { commandId, terminalStatus: "completed" });
  }

  const requestedAfterSeq: number[] = [];
  const server = Bun.serve({
    port: 0,
    fetch(request) {
      const url = new URL(request.url);
      const afterSeq = Number(url.searchParams.get("afterSeq") ?? "0");
      const limit = Number(url.searchParams.get("limit") ?? "500");
      requestedAfterSeq.push(afterSeq);
      return Response.json({ ok: true, data: { items: events.filter((event) => Number(event.seq) > afterSeq).slice(0, limit) } });
    },
  });
  const configPath = `/tmp/unidesk-agentrun-reuse-summary-${process.pid}-${Date.now()}.yaml`;
  const previousConfig = process.env.AGENTRUN_CLIENT_CONFIG;
  const previousKey = process.env.HWLAB_API_KEY;
  process.env.AGENTRUN_CLIENT_CONFIG = configPath;
  process.env.HWLAB_API_KEY = "fixture-secret";
  await Bun.write(configPath, `version: 1\nkind: AgentRunConfig\nmetadata:\n  name: agentrun\nmanager:\n  baseUrl: ${server.url.href}\n  timeoutMs: 15000\nauth:\n  env: HWLAB_API_KEY\n  file: /tmp/hwlab-api-key.env\n  header: Authorization\n  scheme: Bearer\nclient:\n  role: render-only\n  transport: direct-http\n  sessionPolicy:\n    tenantId: unidesk\n    projectId: test\n    providerId: NC01\n    backendProfile: codex\n    workspaceRef:\n      kind: opaque\n    executionPolicy:\n      sandbox: workspace-write\n      approval: never\n      timeoutMs: 600000\n      network: enabled\n      secretScope:\n        allowCredentialEcho: false\n`);
  try {
    const result = await runAgentRunCommand(null, ["events", `run/${RUN_ID}`, "--aggregate", "reuse", "-o", "json"]);
    if (!result.ok) throw new Error("renderedText" in result ? result.renderedText : "AgentRun CLI failed");
    const payload = JSON.parse("renderedText" in result ? result.renderedText : "{}") as Record<string, unknown>;
    expect(payload).toMatchObject({
      kind: "AgentRunReuseSummary",
      runId: RUN_ID,
      eventCount: events.length,
      pageCount: 2,
      commandCount: 5,
      runnerJobCreated: 1,
      runnerSourceFetchStarted: 1,
      resourceBundleMaterialized: 1,
      codexAppServerReused: 4,
      threadResumeCompleted: 4,
      backendTurnStarted: 5,
      commandTerminal: 5,
      reusePassed: true,
      valuesPrinted: false,
    });
    expect(payload.commandIds).toEqual(commandIds);
    expect((payload.terminalStatuses as unknown[]).length).toBe(5);
    expect(requestedAfterSeq).toEqual([0, 500]);

    const invalid = await runAgentRunCommand(null, ["events", `run/${RUN_ID}`, "--aggregate", "reuse", "--after-seq", "1"]);
    expect(invalid.ok).toBe(false);
    expect("renderedText" in invalid ? invalid.renderedText : "").toContain("--aggregate reuse cannot be combined with --after-seq");
  } finally {
    server.stop(true);
    rmSync(configPath, { force: true });
    if (previousConfig === undefined) delete process.env.AGENTRUN_CLIENT_CONFIG;
    else process.env.AGENTRUN_CLIENT_CONFIG = previousConfig;
    if (previousKey === undefined) delete process.env.HWLAB_API_KEY;
    else process.env.HWLAB_API_KEY = previousKey;
  }
});
