import { writeFile } from "node:fs/promises";
import { expect } from "e2e";
import { T3_HOME } from "../e2e.config.ts";
import { makeState, runPromise, test, WEB } from "./t3.ts";

test("Stop during provider startup releases the provider for the next turn", WEB, async ({ t3, app, screen, browser }) => {
  const { cli } = makeState(T3_HOME);
  const failures: string[] = [];
  {
    // Redact synthetic workspace paths in captures without changing server behavior.
    await browser.addInitScript(() => {
      const redact = () => {
        const walker = document.createTreeWalker(document.documentElement, NodeFilter.SHOW_TEXT);
        let node;
        while ((node = walker.nextNode())) {
          if (node.parentElement?.closest("script,style")) continue;
          const text = node.textContent ?? "";
          if (text.includes("/home/")) node.textContent = text.replace(/\/home\/[^\s`"'<>]+/g, "[synthetic workspace]");
        }
      };
      new MutationObserver(redact).observe(document, { childList: true, subtree: true, characterData: true });
    });
    const project = await t3.project("stop-race", { "src/math.ts": "export const sum = 1 + 1;\n" });
    await t3.open();
    for (let attempt = 1; attempt <= 3; attempt++) {
      const title = `Stop race ${attempt}`;
      await t3.thread({ project, title, messages: ["Start"], model: "showcase" });
      const listed = JSON.parse((await runPromise(cli(["thread", "list", "--project", project, "--json"]))).stdout);
      const threadId = listed.find((thread: { title: string }) => thread.title === title).threadId;
      await screen.getByRole("button", `${title}, Done, stop-race`).tap();
      await runPromise(cli(["thread", "race", threadId, `Stop this immediately ${attempt}`]));
      const followup = await runPromise(cli(["thread", "send", threadId, `Follow-up after Stop ${attempt}`, "--wait", "--json"], [0, 1, 2]));
      if (followup.exitCode !== 0) failures.push(followup.stderr + followup.stdout);
      await browser.reload();
      await screen.getByText(`Follow-up after Stop ${attempt}`, { exact: false }).first().waitFor({ state: "attached" });
      await screen.getByText(`Follow-up after Stop ${attempt}`, { exact: false }).first().scrollIntoView();
      await app.screenshot(`follow-up-${attempt}`);
      if (process.env.EVIDENCE_OUTPUT_DIR) {
        await writeFile(`${process.env.EVIDENCE_OUTPUT_DIR}/attempt-${attempt}.json`, JSON.stringify({
          attempt, followupExitCode: followup.exitCode,
          result: JSON.parse(followup.stdout),
        }, null, 2));
      }
    }
    await expect(failures.join("\n")).toBe("");
  }
});
