import { test } from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import {
  EXPECTED_AI_TOOLS,
  EXPECTED_WORK_TOOLS,
  EXPECTED_WEB_SEND_TOOLS,
  EXPECTED_WEB_SYNC_TOOLS,
  parityFailures,
  registeredMcpTools,
} from "./parity-test.ts";

const here = path.dirname(fileURLToPath(import.meta.url));
const mcpSrc = fs.readFileSync(path.join(here, "..", "dewx-mcp.ts"), "utf8");

test("parity guard covers registered sync_* and web send tools", () => {
  assert.deepEqual(parityFailures(mcpSrc), []);
  const registered = registeredMcpTools(mcpSrc);
  for (const name of [...EXPECTED_WEB_SYNC_TOOLS, ...EXPECTED_WEB_SEND_TOOLS, ...EXPECTED_AI_TOOLS, ...Object.keys(EXPECTED_WORK_TOOLS)]) {
    assert.equal(registered.has(name), true, `${name} should be registered on the MCP surface`);
  }
});

test("parity guard fails when a new sync_* tool is not added to the guard list", () => {
  const failures = parityFailures(`${mcpSrc}\nserver.tool("sync_delta", {}, async () => ({}));`);
  assert.match(failures.join("\n"), /sync_delta.*NO parity guard entry/);
});

test("parity guard fails if send_message loses the web reply route", () => {
  const failures = parityFailures(mcpSrc.replace("websync.sendReply(", "websync.sendDisabled("));
  assert.match(failures.join("\n"), /send_message web route is missing web send client/);
});

test("parity guard fails when a new ai_* tool is not added to the guard list", () => {
  const failures = parityFailures(`${mcpSrc}\nserver.tool("ai_triage_inbox", {}, async () => ({}));`);
  assert.match(failures.join("\n"), /ai_triage_inbox.*NO parity guard entry/);
});
