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

test("Successful checkout survives 1.3 MB of hook output", WEB, async ({ t3, app, screen, browser }) => {
  const project = await t3.project("Noisy checkout", { "README.md": "Checkout proof\n" });
  const hook = join(project, ".git/hooks/post-checkout");
  await writeFile(hook, '#!/bin/sh\nhead -c 1300000 /dev/zero | tr "\\000" "x"\nprintf "\\n"\nexit 0\n');
  await chmod(hook, 0o755);
  // Redact only the synthetic repository path, wherever the UI displays it.
  await browser.addInitScript((privatePath: string) => {
    const redact = () => {
      const walker = document.createTreeWalker(document, NodeFilter.SHOW_TEXT);
      let node: Node | null;
      while ((node = walker.nextNode())) {
        if (node.nodeValue?.includes(privatePath)) {
          node.nodeValue = node.nodeValue.split(privatePath).join("[repository]");
        }
      }
    };
    new MutationObserver(redact).observe(document, { childList: true, subtree: true, characterData: true });
  }, project);
  await t3.open();
  await screen.getByRole("button", /Showcase/).tap();
  await screen.getByRole("option", /Multi turn/).tap();
  await browser.keyboard.press("Escape");
  await screen.getByRole("combobox", "Workspace").tap();
  await screen.getByRole("option", "New worktree").tap();
  await screen.getByRole("textbox").fill("Start after the noisy checkout");
  await screen.getByRole("textbox").press("Enter");
  // Capture both outcomes before the assertion so the failure has the same labelled frame.
  await browser.evaluate(async () => {
    await new Promise<void>((resolve) => {
      const ready = () => /first fixture turn complete|Git output exceeded/.test(document.body.innerText);
      if (ready()) return resolve();
      const observer = new MutationObserver(() => { if (ready()) { observer.disconnect(); resolve(); } });
      observer.observe(document.body, { childList: true, subtree: true, characterData: true });
    });
  });
  let previous: Buffer | undefined;
  let settled = false;
  for (let i = 0; i < 20; i++) {
    const path = await app.screenshot(`settling-${i}`);
    const current = await readFile(path);
    const text = await browser.evaluate(() => document.body.innerText);
    if (previous?.equals(current) && !/Working\s+1/.test(text)) { settled = true; break; }
    previous = current;
    await new Promise((resolve) => setTimeout(resolve, 500));
  }
  if (!settled) throw new Error("Capture did not settle");
  await app.screenshot("checkout-result");
  await expect(screen.getByText("first fixture turn complete", { exact: true })).toBeVisible();
});
