/// <reference lib="dom" />
import { mkdir, rename, symlink, readFile, lstat } from "node:fs/promises";
import { join } from "node:path";
import { expect } from "e2e";
import { T3_HOME } from "../e2e.config.ts";
import { test, WEB } from "./t3.ts";

test("Settings save preserves a symlink to a 255-byte filename", WEB, async ({ t3, app, screen, browser }) => {
  await t3.project("demo");
  await t3.open("/settings/worktrees");
  const toggle = screen.getByRole("switch", "Start new worktrees from remote by default");
  await toggle.waitFor();
  const settings = join(T3_HOME, "userdata/settings.json");
  const destination = join(T3_HOME, "dotfiles", "s".repeat(250) + ".json");
  await mkdir(join(T3_HOME, "dotfiles"), { recursive: true });
  await rename(settings, destination);
  await symlink(destination, settings);
  // Public captures replace the sandbox path in server error text.
  await browser.evaluate((home) => {
    const sanitize = () => {
      const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
      while (walker.nextNode()) {
        const node = walker.currentNode;
        if (node.textContent?.includes(home)) node.textContent = node.textContent.replaceAll(home, "<T3 home>");
      }
    };
    new MutationObserver(sanitize).observe(document.body, { childList: true, subtree: true, characterData: true });
  }, T3_HOME);
  await toggle.tap();
  // Wait for either the rejected save or the persisted update before capturing.
  for (let attempt = 0; attempt < 100; attempt++) {
    const saved = JSON.parse(await readFile(destination, "utf8")).newWorktreesStartFromOrigin === false;
    const rejected = await browser.evaluate(() => document.body.innerText.includes("Setting not saved"));
    if (saved || rejected) break;
    await new Promise((resolve) => setTimeout(resolve, 100));
  }
  await new Promise((resolve) => setTimeout(resolve, 800));
  await app.screenshot("settings-save-result");
  await expect(toggle).not.toBeChecked();
  expect(JSON.parse(await readFile(destination, "utf8")).newWorktreesStartFromOrigin).toBe(false);
  expect((await lstat(settings)).isSymbolicLink()).toBe(true);
});
