import { expect } from "e2e";
import { test, WEB } from "./t3.ts";

test("Access keeps a pairing link created during the initial snapshot ACK wait", WEB, async ({ t3, app, screen, browser }) => {
  await t3.project("Access race demo");
  await browser.addInitScript(() => {
    const original = WebSocket.prototype.send;
    let accessId: string | number | undefined;
    const state = { held: false, released: false, release: () => {} };
    (window as any).__accessRace = state;
    WebSocket.prototype.send = function(data) {
      if (typeof data !== "string") return original.call(this, data);
      let messages;
      try { const value = JSON.parse(data); messages = Array.isArray(value) ? value : [value]; }
      catch { return original.call(this, data); }
      for (const message of messages) {
        if (message._tag === "Request" && message.tag === "subscribeAuthAccess") accessId = message.id;
        if (message._tag === "Ack" && message.requestId === accessId && !state.held) {
          state.held = true;
          state.release = () => { original.call(this, data); state.released = true; };
          return;
        }
      }
      return original.call(this, data);
    };
  });
  await t3.open();
  await screen.getByText("Access race demo", { exact: true }).first().waitFor({ state: "visible" });
  const origin = await browser.evaluate(() => location.origin);
  const credential = await browser.evaluate(async () => {
    const response = await fetch("/api/auth/pairing-token", {
      method: "POST", headers: { "content-type": "application/json" },
      body: JSON.stringify({ label: "Second authorized client", scopes: ["access:read", "access:write", "orchestration:read"] }),
    });
    if (!response.ok) throw new Error(`Second client credential: HTTP ${response.status}`);
    return (await response.json()).credential as string;
  });
  const session = await fetch(`${origin}/api/auth/browser-session`, {
    method: "POST", headers: { "content-type": "application/json", origin },
    body: JSON.stringify({ credential }),
  });
  if (!session.ok) throw new Error(`Second client sign-in: HTTP ${session.status}`);
  const cookie = session.headers.getSetCookie().map(value => value.split(";")[0]).join("; ");
  if (!cookie) throw new Error("Second client received no session cookie");
  await app.open("/settings/access");
  await browser.evaluate(async () => {
    const deadline = Date.now() + 10000;
    while (!(window as any).__accessRace.held && Date.now() < deadline) await new Promise(r => setTimeout(r, 25));
    if (!(window as any).__accessRace.held) throw new Error("The initial access snapshot ACK was not held");
  });
  // An independent authenticated client commits the change while the real stream waits for ACK.
  const created = await fetch(`${origin}/api/auth/pairing-token`, {
    method: "POST", headers: { "content-type": "application/json", cookie, origin },
    body: JSON.stringify({ label: "Created during snapshot", scopes: ["orchestration:read"] }),
  });
  if (!created.ok) throw new Error(`Concurrent creation: HTTP ${created.status}`);
  await created.text();
  await browser.evaluate(async () => {
    (window as any).__accessRace.release();
    await new Promise(r => setTimeout(r, 1000));
  });
  await screen.getByText("Authorized clients", { exact: true }).tap();
  await screen.getByText("This device", { exact: true }).waitFor({ state: "visible" });
  await browser.evaluate(() => new Promise<null>(resolve => setTimeout(() => resolve(null), 500)));
  await app.screenshot("access-after-concurrent-create");
  await expect(screen.getByText("Created during snapshot", { exact: true })).toBeVisible();
});
