import { spawn } from "node:child_process";
import { mkdtemp } from "node:fs/promises";
import { expect } from "e2e";
import { APP_DIR, T3_HOME } from "../e2e.config.ts";
import { test, WEB } from "./t3.ts";

test("Retry now connects and retains a reachable environment while the platform reports offline", WEB, async ({ t3, app, screen, browser }) => {
  const home = await mkdtemp(`${process.env.T3_RETRY_SCRATCH}/remote-`);
  const remote = spawn(process.execPath, ["apps/server/src/bin.ts", "--host", "127.0.0.1", "--port", "47911", "--base-dir", home, "--no-browser"], {
    cwd: APP_DIR,
    env: { ...process.env, PATH: `${T3_HOME}/bin:${process.env.PATH}`, T3CODE_DEV_SEED: "0", T3CODE_AUTO_BOOTSTRAP_PROJECT_FROM_CWD: "0" },
    stdio: ["ignore", "pipe", "pipe"],
  });
  try {
    const pairing = await new Promise<string>((resolve, reject) => {
      let output = "";
      const read = (data: Buffer) => {
        output += data.toString();
        const match = /(?:pairingUrl:|Pairing URL:)\s*(http[^\s\u001b]+)/.exec(output);
        if (match) resolve(match[1]);
      };
      remote.stdout.on("data", read);
      remote.stderr.on("data", read);
      remote.once("exit", (code) => reject(new Error(`Remote server exited ${code}`)));
    });
    await t3.project("Offline retry demo");
    await t3.open("/settings/connections");
    const online = await browser.evaluate(() => navigator.onLine);
    if (online) throw new Error("Reproduction requires native navigator.onLine=false in loopback-only namespace");
    await screen.getByRole("button", "Add environment").tap();
    await screen.getByRole("textbox", "Host").fill(pairing);
    await screen.getByRole("dialog").getByRole("button", "Add environment").tap();
    await screen.getByRole("button", "Details").tap();
    const reachable = await browser.evaluate(async () => {
      const response = await fetch("http://127.0.0.1:47911/.well-known/t3/environment");
      return response.status === 200 && navigator.onLine === false;
    });
    if (!reachable) throw new Error("Control failed: offline platform must still reach the second server over loopback");
    await app.screenshot("before-retry");
    await screen.getByRole("button", "Retry now").tap();
    await browser.evaluate(async () => {
      await new Promise((resolve) => setTimeout(resolve, 15000));
      return navigator.onLine;
    });
    await app.screenshot("after-retry");
    await expect(screen.getByText("http://127.0.0.1:47911/ · Connected", { exact: true })).toBeVisible();
    if (await browser.evaluate(() => navigator.onLine)) throw new Error("Platform changed online during retry");
  } finally {
    remote.kill("SIGTERM");
    await new Promise<void>((resolve) => remote.once("exit", () => resolve()));
  }
});
