import { createServer } from "node:http";
import { expect } from "e2e";
import { test, WEB } from "./t3.ts";

test("Link discovery explains each failed address", WEB, async ({ t3, app, screen, browser }) => {
  const html = createServer((_request, response) => {
    response.writeHead(200, { "Content-Type": "text/html" });
    response.end("<!doctype html><title>Example site</title><p>This is a website.</p>");
  });
  await new Promise<void>((resolve) => html.listen(49998, "127.0.0.1", resolve));
  try {
    await t3.project("Link discovery");
    await t3.open();
    await screen.getByRole("button", "Add project").waitFor({ state: "visible" });
    await app.open("/settings/labs");
    await screen.getByRole("switch", "Linked environments").tap();
    for (const [label, address, diagnostic] of [
      ["refused-connection", "http://127.0.0.1:49999", "ECONNREFUSED"],
      ["unresolvable-host", "https://discovery-proof-nonexistent.ts.net", "ENOTFOUND"],
      ["incompatible-html", "http://127.0.0.1:49998", "answered, but not as a T3 Code environment this version understands"],
    ]) {
      await app.open("/settings/connections");
      await screen.getByRole("button", "Link", { exact: true }).tap();
      await screen.getByRole("textbox", "Address", { exact: true }).fill(address!);
      await screen.getByRole("textbox", "Pairing code", { exact: true }).fill("synthetic-discovery-code");
      await screen.getByRole("button", "Link", { exact: true }).last().tap();
      await screen.getByText("Could not link the environment", { exact: true }).waitFor({ state: "visible" });
      await browser.evaluate(async () => {
        await Promise.all(document.getAnimations().map((animation) => animation.finished.catch(() => {})));
        return true;
      });
      await app.screenshot(label!);
      await expect.soft(screen.getByText(diagnostic!, { exact: false })).toBeVisible();
    }
  } finally {
    html.closeAllConnections();
    await new Promise<void>((resolve, reject) => html.close((error) => error ? reject(error) : resolve()));
  }
});
