import { expect } from "e2e";
import { execFileSync } from "node:child_process";
import { writeFileSync, existsSync } from "node:fs";
import { test, WEB } from "./t3.ts";

test("Selected-file commit preserves a conflicted cherry-pick", WEB, async ({ t3, app, screen, browser }) => {
  const project = await t3.project("sample-pick", { "README.md": "# Sample pick\n" });
  const git = (...args: string[]) => execFileSync("git", args, { cwd: project, encoding: "utf8" }).trim();
  git("config", "user.name", "Test User");
  git("config", "user.email", "test@example.invalid");
  git("switch", "-c", "other");
  writeFileSync(`${project}/README.md`, "# Sample pick\nLine from the other branch.\n");
  writeFileSync(`${project}/picked.txt`, "picked content\n");
  git("add", "README.md", "picked.txt");
  git("-c", "user.name=Sample Author", "-c", "user.email=author@example.com", "commit", "-m", "Add picked file and README line");
  git("switch", "main");
  writeFileSync(`${project}/README.md`, "# Sample pick\nLine from main.\n");
  git("commit", "-am", "Main README line");
  try { git("cherry-pick", "other"); } catch {}
  writeFileSync(`${project}/README.md`, "# Sample pick\nLine from main.\nLine from the other branch.\n");
  git("add", "README.md");
  const originalHead = git("rev-parse", "HEAD");
  await t3.thread({ project, title: "Cherry-pick selected files", messages: ["Ready"] });
  await t3.open();
  await screen.getByTestId("sidebar-row-card").press("Enter");
  // Redact only the synthetic repository's absolute path from error toasts and recordings.
  await browser.evaluate((workspace: string) => {
    const redact = (node: Node) => {
      if (node.nodeType === Node.TEXT_NODE && node.textContent?.includes(workspace)) {
        node.textContent = node.textContent.replaceAll(workspace, "[sample-pick repository]");
      } else {
        for (const child of node.childNodes) redact(child);
      }
    };
    new MutationObserver((records) => {
      for (const record of records) {
        if (record.type === "characterData") redact(record.target);
        else for (const node of record.addedNodes) redact(node);
      }
    }).observe(document.body, { childList: true, subtree: true, characterData: true });
  }, project);
  await screen.getByRole("button", "Git action options").tap();
  await screen.getByRole("menuitem", "Commit", { exact: true }).tap();
  await screen.getByRole("button", "Edit", { exact: true }).tap();
  await screen.getByRole("checkbox").nth(2).tap();
  await screen.getByPlaceholder("Leave empty to auto-generate").fill("Add picked file");
  await app.screenshot("selected-picked-file");
  await screen.getByRole("button", "Commit", { exact: true }).tap();
  // Completion is a success toast on base and a refusal toast on head.
  await screen.getByText(/Committed [a-f0-9]+|Cannot commit selected files|Cannot commit specific files|cherry-pick.*progress/i).first().waitFor({ state: "visible" });
  await browser.evaluate(async () => {
    await Promise.all(document.getAnimations().map((animation) => animation.finished.catch(() => {})));
  });
  await app.screenshot("commit-result");
  console.log(JSON.stringify({ head: git("log", "-1", "--format=%h %an %s"), status: git("status", "--short"), cherryPickInProgress: existsSync(`${project}/.git/CHERRY_PICK_HEAD`) }));
  await expect(existsSync(`${project}/.git/CHERRY_PICK_HEAD`)).toBe(true);
  await expect(git("rev-parse", "HEAD")).toBe(originalHead);
  await expect(git("status", "--short")).toBe("M  README.md\nA  picked.txt");
});
