import { expect } from "e2e";
import { writeFile, readFile, mkdir } from "node:fs/promises";
import { join } from "node:path";
import { execFile as execFileCallback } from "node:child_process";
import { promisify } from "node:util";
import { APP_DIR, T3_HOME } from "../e2e.config.ts";
import { test, WEB } from "./t3.ts";

test("Inline extensionless project paths become file chips", WEB, async ({ t3, app, screen, browser }) => {
  const paths = ["docker/Dockerfile", "./docker/Dockerfile", "docker/Dockerfile:3", "src/Makefile", "./src/Makefile", "docs/README", "docs/README:1", "src/main.ts", "origin/main", "z-ai/glm-5.3"];
  const text = "Inline file path examples\n\n" + paths.map(p => "- `" + p + "`").join("\n");
  const frames = [
    { type: "expect_outbound", frame: { kind: "request", method: "session/prompt", params: {} } },
    { type: "emit_inbound", frame: { kind: "notification", method: "session/update", params: { sessionId: "sample", update: { sessionUpdate: "agent_message_chunk", content: { type: "text", text } } } } },
    { type: "emit_inbound", frame: { kind: "response", method: "session/prompt", result: { stopReason: "end_turn" } } }
  ];
  await writeFile(join(APP_DIR, "apps/server/scripts/dev-replay/command_output_transcript.ndjson"), frames.map(f => JSON.stringify(f)).join("\n") + "\n");
  const project = await t3.project("file-chip-sample", { "docker/Dockerfile": "FROM scratch\n\nCMD []\n", "src/Makefile": "all:\n\techo done\n", "docs/README": "Sample documentation\n", "src/main.ts": "export {};\n" });
  const thread = await t3.thread({ project, title: "Inline path examples", messages: ["Show inline file path examples"], model: "command-output" });
  await t3.open(thread);
  await screen.getByText("z-ai/glm-5.3", { exact: true }).waitFor({ state: "visible" });
  await screen.getByText("Syncing messages...", { exact: true }).waitFor({ state: "hidden" });
  await app.screenshot("inline-file-paths");
  await browser.keyboard.press("Control+f");
  await screen.getByRole("searchbox", "Find in thread").fill("Dockerfile");
  await screen.getByText("1/3", { exact: true }).waitFor({ state: "visible" });
  await app.screenshot("thread-find-file-paths");
  await screen.getByRole("button", "Close find").tap();
  await screen.getByRole("combobox", "Search threads").fill("Dockerfile");
  await screen.getByRole("listbox", "Thread search results").waitFor({ state: "visible" });
  await app.screenshot("thread-search-file-paths");
  await screen.getByRole("combobox", "Search threads").fill("");
  if (process.env.PROOF_CAPTURE_DIR) {
    const execFile = promisify(execFileCallback);
    const revision = (await execFile("git", ["rev-parse", "HEAD"], {cwd: APP_DIR})).stdout.trim();
    const output = join(process.env.PROOF_CAPTURE_DIR, revision, String(Date.now()));
    await mkdir(output, {recursive:true});
    const desktopDir = join(APP_DIR, "apps/desktop");
    await execFile(process.execPath, ["node_modules/electron/install.js"], {cwd: desktopDir});
    await execFile(process.execPath, ["scripts/build-preview-annotation-css.mjs"], {cwd: desktopDir});
    await execFile("vp", ["pack"], {cwd: desktopDir, maxBuffer: 10000000});
    let result;
    try { result = await execFile("headless-desktop", [process.execPath, new URL("./desktop-inline-driver.mjs", import.meta.url).pathname, APP_DIR, app.baseUrl, join(T3_HOME,"pairing-path"), await browser.evaluate<string>("location.href"), output], {timeout: 120000, maxBuffer:10000000});
    } catch (error) {
      await writeFile(join(output,"desktop-error.txt"), String(error.stderr ?? "") + "\n" + String(error.stdout ?? ""));
      result = { stdout: "Desktop capture failed; see desktop-error.txt" };
    }
    await writeFile(join(output,"desktop-observation.json"),result.stdout);
  }
  const chips = await browser.evaluate<string[]>(`[...document.querySelectorAll('a')].filter(a => a.getAttribute('href')?.includes('file-chip-sample')).map(a => a.textContent)`);
  await expect(chips).toContain("Dockerfile");
  await expect(await browser.evaluate<number>(`[...document.querySelectorAll('code[data-inline-code]')].filter(e => ['docker/Dockerfile','src/Makefile','docs/README'].includes(e.textContent)).length`)).toBe(0);
});
