import { expect } from "e2e";
import { readFile, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { APP_DIR } from "../e2e.config.ts";
import { test, WEB } from "./t3.ts";

test("Root tool output keeps the replacement and appends later chunks", WEB, async ({ t3, app, screen }) => {
  // Configure only the synthetic agent; the adapter and clients are the tested commit's code.
  const agent = join(APP_DIR, "apps/server/scripts/dev-replay-agent.ts");
  const recording = join(APP_DIR, "apps/server/scripts/dev-replay/showcase_transcript.ndjson");
  const originalAgent = await readFile(agent, "utf8");
  const originalRecording = await readFile(recording, "utf8");
  const text = (value: string) => ({ type: "content", content: { type: "text", text: value } });
  const update = (value: object) => ({ type: "emit_inbound", afterMs: 1500, frame: { kind: "notification", method: "session/update", params: { sessionId: "root", update: value } } });
  const frames = [
    { type: "expect_outbound", frame: { kind: "request", method: "session/prompt", params: "<any>" } },
    update({ sessionUpdate: "tool_call_update", toolCallId: "root-output", title: "Root output replacement", kind: "execute", status: "in_progress", rawInput: { command: "echo synthetic-output" }, content: [text("one")] }),
    update({ sessionUpdate: "tool_call_content_chunk", toolCallId: "root-output", content: text("two") }),
    update({ sessionUpdate: "tool_call_update", toolCallId: "root-output", status: "completed", content: [text("replacement")] }),
    update({ sessionUpdate: "tool_call_content_chunk", toolCallId: "root-output", content: text("-more") }),
    update({ sessionUpdate: "agent_message_chunk", content: { type: "text", text: "Replay complete." } }),
    { type: "emit_inbound", frame: { kind: "response", method: "session/prompt", result: { stopReason: "end_turn" } } },
  ];
  try {
    await writeFile(agent, originalAgent.replace('"tool_call_update",', '"tool_call_update",\n  "tool_call_content_chunk",'));
    await writeFile(recording, frames.map(frame => JSON.stringify(frame)).join("\n") + "\n");
    const project = await t3.project("Tool output demo");
    await t3.open();
    await screen.getByRole("textbox").fill("Run the root tool output replacement replay");
    await screen.getByRole("textbox").press("Enter");
    await screen.getByRole("button", { name: /^Worked for/ }).tap();
    await screen.getByText("echo synthetic-output", { exact: false }).first().tap();
    let previous = await app.screenshot("settling-output");
    let stable = false;
    for (let attempt = 0; attempt < 12; attempt++) {
      await new Promise(resolve => setTimeout(resolve, 500));
      const current = await app.screenshot(`stable-check-${attempt}`);
      if ((await readFile(previous)).equals(await readFile(current))) { stable = true; break; }
      previous = current;
    }
    if (!stable) throw new Error("Final capture is not stable");
    await app.screenshot("finished-root-tool-output");
    await expect(screen.getByText("replacement-more", { exact: true })).toBeVisible();
  } finally {
    await writeFile(agent, originalAgent);
    await writeFile(recording, originalRecording);
  }
});
