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

test("Host video permission explanation and thread-find exclusion", WEB, async ({ t3, app, screen, browser }) => {
  const project = await t3.project("video-demo");
  execFileSync("ffmpeg", ["-v", "error", "-f", "lavfi", "-i", "color=c=blue:s=640x360:d=3", "-vf", "drawtext=text=Demo:fontcolor=white:fontsize=48:x=(w-tw)/2:y=(h-th)/2", "-c:v", "libx264", "-pix_fmt", "yuv420p", "-y", `${project}/demo.mp4`]);
  const fixture = `${APP_DIR}/apps/server/scripts/dev-replay/showcase_transcript.ndjson`;
  const original = await readFile(fixture, "utf8");
  const frames = [
    {type:"expect_outbound",frame:{kind:"request",method:"session/prompt",params:"<any>"}},
    {type:"emit_inbound",frame:{kind:"notification",method:"session/update",params:{sessionId:"replay",update:{sessionUpdate:"agent_message_chunk",content:{type:"text",text:"Here is the host video.\n\n![Demo](<workspace>/demo.mp4)"}}}}},
    {type:"emit_inbound",frame:{kind:"response",method:"session/prompt",result:{stopReason:"end_turn"}}}
  ];
  await writeFile(fixture, frames.map(x=>JSON.stringify(x)).join("\n")+"\n");
  let thread;
  try { thread = await t3.thread({project,title:"Host video access",messages:["Show the demo"],model:"showcase"}); }
  finally { await writeFile(fixture, original); }
  const { cli } = makeState(T3_HOME);
  const pair = async (fileAccess: boolean) => {
    const args = ["auth","pairing","create","--base-url",app.baseUrl!,"--scope","orchestration:read","--scope","orchestration:operate"];
    if (fileAccess) args.push("--scope","filesystem:read");
    const result = await runPromise(cli(args));
    const url = /Pair URL:\s*(\S+)/.exec(result.stdout+result.stderr)![1]!;
    await writeFile(`${T3_HOME}/pairing-path`, url);
  };
  await pair(false);
  await t3.open(thread!);
  await screen.getByText("Video unavailable", {exact:false}).waitFor({state:"visible"});
  if (await screen.getByRole("button", "Dismiss").count()) await screen.getByRole("button", "Dismiss").tap();
  await app.screenshot("restricted-host-video");
  // Search the generated failure label, rather than actual message content.
  await browser.keyboard.press("Control+f");
  await screen.getByRole("searchbox", "Find in thread").fill("Video unavailable");
  await screen.getByText("Searching…").waitFor({state:"hidden"});
  await app.screenshot("thread-find-failure-label");
  await expect.soft(screen.getByText("This connection cannot read host files. Pair again with a new link to view it.", {exact:false})).toBeVisible();
  await expect.soft(screen.getByRole("button", "Retry video")).toBeHidden();
  await expect.soft(screen.getByRole("button", "Next match")).toBeDisabled();
  await screen.getByRole("button", "Close find").tap();
  await browser.evaluate(() => { localStorage.clear(); sessionStorage.clear(); });
  await pair(true);
  await t3.open(thread!);
  await browser.locator("video").waitFor({state:"visible"});
  await browser.evaluate(async () => { const video = document.querySelector("video")!; await video.play(); await new Promise<void>(resolve => video.addEventListener("timeupdate", () => { video.pause(); resolve(); }, {once:true})); });
  await app.screenshot("filesystem-read-video-reachable");
});
