"use strict";
var import_widgetContract = require("./widgetContract");
var import_curatedWidgets = require("./curatedWidgets");
const cases = [];
function test(name, run) {
  cases.push({ name, run });
}
function assertEqual(actual, expected, msg) {
  const a = JSON.stringify(actual);
  const e = JSON.stringify(expected);
  if (a !== e)
    throw new Error(`${msg ?? "assertEqual"} \u2014 expected ${e}, got ${a}`);
}
function assertThrows(fn, substring) {
  let threw = false;
  let message = "";
  try {
    fn();
  } catch (e) {
    threw = true;
    message = e.message;
  }
  if (!threw) throw new Error("expected function to throw");
  if (substring && !message.includes(substring))
    throw new Error(`thrown message "${message}" does not include "${substring}"`);
}
const curatedFingerprints = Object.keys(import_curatedWidgets.CURATED);
const firstCurated = curatedFingerprints[0];
test("lookupContract: curated takes precedence over inferred", () => {
  const cache = /* @__PURE__ */ new Map();
  cache.set(firstCurated, {
    source: "inferred",
    confidence: "low",
    widgetIdentification: "cache-shadow attempt",
    parameters: [],
    steps: []
  });
  const result = (0, import_widgetContract.lookupContract)(firstCurated, cache);
  if (result.status !== "found") throw new Error("expected found");
  assertEqual(result.contract.source, "curated");
});
test("lookupContract: inferred returned when no curated entry exists", () => {
  const cache = /* @__PURE__ */ new Map();
  const inferred = {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "CustomDatePicker",
    parameters: ["date"],
    steps: [{ kind: "click", target: "trigger" }]
  };
  cache.set("0000000000000001", inferred);
  const result = (0, import_widgetContract.lookupContract)("0000000000000001", cache);
  if (result.status !== "found") throw new Error("expected found");
  assertEqual(result.contract.source, "inferred");
});
test("lookupContract: unknown fingerprint returns needs_inference_marker", () => {
  const cache = /* @__PURE__ */ new Map();
  const result = (0, import_widgetContract.lookupContract)("ffffffffffffffff", cache);
  assertEqual(result.status, "needs_inference_marker");
});
test("cacheInferredContract: refuses to overwrite curated entry", () => {
  const cache = /* @__PURE__ */ new Map();
  const result = (0, import_widgetContract.cacheInferredContract)(firstCurated, {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "X",
    parameters: [],
    steps: []
  }, cache);
  assertEqual(result, { ok: false, error: "fingerprint collides with curated entry; cannot overwrite" });
});
test("cacheInferredContract: accepts valid inferred contract", () => {
  const cache = /* @__PURE__ */ new Map();
  const result = (0, import_widgetContract.cacheInferredContract)("0000000000000002", {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "X",
    parameters: ["v"],
    steps: [{ kind: "fill", target: "inputByLabel", label: "Name", param: "v" }]
  }, cache);
  assertEqual(result, { ok: true });
  assertEqual(cache.size, 1);
});
test("cacheInferredContract: overwrites previous inferred contract (mutable)", () => {
  const cache = /* @__PURE__ */ new Map();
  (0, import_widgetContract.cacheInferredContract)("0000000000000003", {
    source: "inferred",
    confidence: "low",
    widgetIdentification: "bad",
    parameters: [],
    steps: []
  }, cache);
  (0, import_widgetContract.cacheInferredContract)("0000000000000003", {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "good",
    parameters: [],
    steps: []
  }, cache);
  assertEqual(cache.get("0000000000000003").widgetIdentification, "good");
});
test("cacheInferredContract: accepts unknown stub", () => {
  const cache = /* @__PURE__ */ new Map();
  const result = (0, import_widgetContract.cacheInferredContract)("0000000000000004", {
    source: "unknown",
    confidence: "low",
    widgetIdentification: "",
    parameters: [],
    steps: []
  }, cache);
  assertEqual(result, { ok: true });
});
test("cacheInferredContract: rejects source=curated (defense in depth)", () => {
  const cache = /* @__PURE__ */ new Map();
  const result = (0, import_widgetContract.cacheInferredContract)("0000000000000005", {
    source: "curated",
    confidence: "high",
    widgetIdentification: "forged",
    parameters: [],
    steps: []
  }, cache);
  if (result.ok)
    throw new Error("expected reject when source=curated");
  if (!result.error.includes("source: 'curated'"))
    throw new Error(`expected error message to mention curated, got: ${result.error}`);
  assertEqual(cache.size, 0);
});
test("validateContract: step.param must exist in parameters[]", () => {
  const c = {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "X",
    parameters: ["v"],
    steps: [{ kind: "click", target: "option", matchBy: "accessibleName", param: "w" }]
  };
  assertThrows(() => (0, import_widgetContract.validateContract)(c), "param 'w'");
});
test("validateContract: EnterFrameStep.framePath must be non-empty", () => {
  const c = {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "X",
    parameters: [],
    steps: [{ kind: "enterFrame", framePath: [] }, { kind: "exitFrame" }]
  };
  assertThrows(() => (0, import_widgetContract.validateContract)(c), "framePath");
});
test("validateContract: rule 1 (missing param) is reported before rule 2 (empty framePath)", () => {
  const c = {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "X",
    parameters: [],
    steps: [
      { kind: "click", target: "option", matchBy: "accessibleName", param: "v" },
      { kind: "enterFrame", framePath: [] }
    ]
  };
  assertThrows(() => (0, import_widgetContract.validateContract)(c), "param 'v'");
});
test("validateContract: at most one EnterFrameStep", () => {
  const c = {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "X",
    parameters: [],
    steps: [
      { kind: "enterFrame", framePath: ["iframe"] },
      { kind: "exitFrame" },
      { kind: "enterFrame", framePath: ["iframe"] }
    ]
  };
  assertThrows(() => (0, import_widgetContract.validateContract)(c), "EnterFrameStep");
});
test("validateContract: HandoffStep-before-WaitForStep is a warning, not an error", () => {
  const c = {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "X",
    parameters: [],
    steps: [{ kind: "click", target: "trigger" }, { kind: "handoff" }]
  };
  (0, import_widgetContract.validateContract)(c);
});
test("validateContract: widgetIdentification length is NOT enforced here (Zod schema concern)", () => {
  const c = {
    source: "inferred",
    confidence: "high",
    widgetIdentification: "a".repeat(200),
    parameters: [],
    steps: []
  };
  (0, import_widgetContract.validateContract)(c);
});
let failed = 0;
for (const { name, run } of cases) {
  try {
    run();
    console.log("  \u2713", name);
  } catch (e) {
    failed++;
    console.log("  \u2717", name);
    console.log("     ", e.message);
  }
}
if (failed > 0) {
  console.log(`
${failed}/${cases.length} failed`);
  process.exit(1);
}
console.log(`
${cases.length} passed`);
