import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { test } from "bun:test";

import { rootPath } from "./config";
import { hwlabRuntimeLaneSpecForNode } from "./hwlab-node-lanes";
import { nodeWebProbeNativeReadinessScript, parseWebProbeNativeReadinessProfiles } from "./hwlab-node-web-probe-native-readiness";
import { parseNodeWebProbeOptions } from "./hwlab-node/web-probe";

function fixtureProfile(): Record<string, unknown> {
  return {
    application: "workbench",
    path: "/tool",
    navigationTimeoutMs: 30000,
    settleMs: 100,
    commandTimeoutSeconds: 120,
    viewport: { width: 1280, height: 720 },
    readySelectors: ["#app", "button.toggle"],
    minBodyTextLength: 8,
    contentReadiness: {
      settledSelector: "#list:not([data-loading='true'])",
      itemSelector: ".item",
      selectedSelector: ".item[data-active='true']",
      contentSelector: ".content",
      timeoutMs: 20000,
    },
    geometryChecks: [{ selector: ".quiet-status", maxHeightPx: 40, required: false }],
    interaction: { selector: "button.toggle", observedSelector: "aside.panel", observedAttribute: "data-collapsed" },
    failedResponseStatus: 400,
    criticalPathPrefixes: ["/api/"],
    screenshotName: "ready.png",
    outputLimits: { errors: 10, failedResponses: 10, textPreviewChars: 120 },
    layout: {
      requireNoDocumentOverflow: true,
      requireNoMainContentOverflow: true,
      mainContentSelector: ".platform-content",
      internalScrollSelectors: [".records"],
    },
  };
}

test("native readiness profile is owned by lane YAML", () => {
  const spec = hwlabRuntimeLaneSpecForNode("v03", "NC01");
  assert.equal(spec.webProbe?.defaultNativeReadinessProfile, "workbench");
  const profile = spec.webProbe?.nativeReadinessProfiles?.workbench;
  assert.ok(profile);
  assert.equal(profile.path, "/workbench");
  assert.equal(profile.application, "workbench");
  assert.deepEqual(profile.readySelectors, ["#workspace", ".desktop-sidebar-toggle"]);
  assert.equal(profile.contentReadiness?.settledSelector, "#session-tabs:not([data-loading='true'])");
  assert.equal(profile.geometryChecks?.[0]?.maxHeightPx, 40);
  assert.equal(profile.interaction.observedSelector, ".platform-sidebar");
  assert.equal(profile.interaction.observedAttribute, "data-collapsed");
  assert.equal(spec.nativeDevelopment?.workbench.publicExposure.publicBaseUrl, "https://lab-dev-workbench.hwpod.com");
  assert.equal(spec.nativeDevelopment?.workbench.web.port, 5174);
  assert.equal(spec.webProbe?.nativeReadinessProfiles?.hwpod?.application, "hwpod");
  assert.equal(spec.webProbe?.nativeReadinessProfiles?.hwpod?.authentication, "none");
  assert.equal(spec.nativeDevelopment?.hwpod.publicExposure.publicBaseUrl, "https://lab-dev-hwpod.hwpod.com");
  assert.equal(spec.webProbe?.nativeReadinessProfiles?.caserun?.layout?.requireNoDocumentOverflow, true);
  assert.deepEqual(spec.webProbe?.nativeReadinessProfiles?.caserun?.layout?.internalScrollSelectors, [".caserun-run-list", ".caserun-events", ".evidence-body"]);
});

test("native readiness profile rejects unknown fields", () => {
  assert.throws(() => parseWebProbeNativeReadinessProfiles({ fixture: { ...fixtureProfile(), fallbackUrl: "http://example.test" } }, "fixture.profiles"), /unsupported fields: fallbackUrl/u);
});

test("generated native readiness script is valid and generic", () => {
  const profile = parseWebProbeNativeReadinessProfiles({ fixture: fixtureProfile() }, "fixture.profiles").fixture;
  assert.ok(profile);
  const script = nodeWebProbeNativeReadinessScript("fixture", profile, "config/example.yaml#profiles.fixture");
  assert.doesNotThrow(() => new Function(script.replace("export default ", "")));
  assert.match(script, /page\.on\("console"/u);
  assert.match(script, /message\.location\(\)/u);
  assert.match(script, /page\.on\("pageerror"/u);
  assert.match(script, /page\.on\("requestfailed"/u);
  assert.match(script, /interactionChanged/u);
  assert.match(script, /contentReadiness/u);
  assert.match(script, /geometryReady/u);
  assert.match(script, /noDocumentOverflow/u);
  assert.match(script, /internalScrollPanesReady/u);
  assert.match(script, /jsonArtifact\("native-web-readiness\.json"/u);
  const source = readFileSync(rootPath("scripts/src/hwlab-node-web-probe-native-readiness.ts"), "utf8");
  assert.doesNotMatch(source, /NC01|v03|152\.53\.229\.148|5173|#workspace|desktop-sidebar-toggle/u);
});

test("native-readiness is one managed command resolved from owning YAML", () => {
  const options = parseNodeWebProbeOptions(["native-readiness", "--node", "NC01", "--lane", "v03", "--profile", "workbench"]);
  assert.equal(options.action, "script");
  if (options.action !== "script") return;
  assert.equal(options.url, "https://lab-dev-workbench.hwpod.com");
  assert.equal(options.originName, "custom");
  assert.equal(options.viewport, "1920x1080");
  assert.equal(options.commandTimeoutSeconds, 120);
  assert.equal(options.suppressAdHocWarning, true);
  assert.equal(options.scriptSource.path, "builtin:native-readiness/workbench");
  assert.match(options.commandLabel ?? "", /web-probe native-readiness/u);
  const managedRunner = readFileSync(rootPath("scripts/src/hwlab-node/web-observe-scripts.ts"), "utf8");
  assert.match(managedRunner, /asyncJob !== null \? "remote-artifact-job-report"/u);
});

test("HWPOD native-readiness resolves the independent L1 Web origin", () => {
  const options = parseNodeWebProbeOptions(["native-readiness", "--node", "NC01", "--lane", "v03", "--profile", "hwpod"]);
  assert.equal(options.action, "script");
  if (options.action !== "script") return;
  assert.equal(options.url, "https://lab-dev-hwpod.hwpod.com");
  assert.equal(options.viewport, "1920x1080");
  assert.equal(options.authentication, "none");
  assert.equal(options.scriptSource.path, "builtin:native-readiness/hwpod");
});

test("CaseRun native readiness resolves the CaseRun YAML HTTPS origin", () => {
  const options = parseNodeWebProbeOptions(["native-readiness", "--node", "NC01", "--lane", "v03", "--profile", "caserun"]);
  assert.equal(options.action, "script");
  if (options.action !== "script") return;
  assert.equal(options.url, "https://lab-dev-caserun.hwpod.com");
  assert.match(options.originConfigPath ?? "", /nativeDevelopment\.caserun/u);
});

test("native-readiness rejects URL and origin overrides", () => {
  assert.throws(() => parseNodeWebProbeOptions(["native-readiness", "--node", "NC01", "--lane", "v03", "--url", "http://127.0.0.1:5173"]), /unknown option: --url/u);
  assert.throws(() => parseNodeWebProbeOptions(["native-readiness", "--node", "NC01", "--lane", "v03", "--origin", "public"]), /unknown option: --origin/u);
});
