import { test } from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

const here = dirname(fileURLToPath(import.meta.url));
const src = readFileSync(join(here, "dashboard.js"), "utf8");

// A WIRING check, not a behavioural one — deliberately.
//
// The error net is browser-only (window.addEventListener) and CI blocks browser
// downloads (.github/workflows/ci.yml sets PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD), so
// there is no DOM here to fire a real unhandledrejection into. What this can do
// is assert the net exists and is actually installed — which is the failure mode
// that matters, because the net silently not being wired up is indistinguishable
// from the bug it exists to prevent.

test("the global error net is defined", () => {
  assert.match(src, /function installGlobalErrorNet\(\)/, "installGlobalErrorNet must exist");
});

test("it listens for BOTH unhandled rejections and uncaught errors", () => {
  const fn = src.slice(src.indexOf("function installGlobalErrorNet()"));
  const body = fn.slice(0, fn.indexOf("\nasync function init()"));
  assert.match(
    body,
    /addEventListener\(\s*["']unhandledrejection["']/,
    "rejections must be caught",
  );
  assert.match(body, /addEventListener\(\s*["']error["']/, "uncaught errors must be caught");
  // A rejected promise with no handler is the common case in this codebase —
  // async renderers are called without await in several places.
  assert.match(body, /toast\(/, "the user must actually be told");
});

test("it is installed from init(), before the first await", () => {
  const initFn = src.slice(src.indexOf("async function init()"));
  const head = initFn.slice(0, initFn.indexOf("await"));
  assert.match(
    head,
    /installGlobalErrorNet\(\)/,
    "the net must be armed before any awaited startup work, or a failure during " +
      "startup leaves a blank page with no explanation",
  );
});

test("it does not toast on resource-load errors", () => {
  const fn = src.slice(src.indexOf("function installGlobalErrorNet()"));
  const body = fn.slice(0, fn.indexOf("\nasync function init()"));
  // window 'error' also fires for a failed <img>/<script> load, with no
  // e.error. Toasting those would train the user to ignore the net.
  assert.match(body, /if \(!e\?\.error\) return;/, "resource-load errors must be ignored");
});

test("it is rate-limited so one bad loop cannot spam the user", () => {
  const fn = src.slice(src.indexOf("function installGlobalErrorNet()"));
  const body = fn.slice(0, fn.indexOf("\nasync function init()"));
  assert.match(body, /lastShownAt/, "repeated failures must collapse into one message");
});
