#!/usr/bin/env node

import http from "node:http";
import { spawn } from "node:child_process";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";

let reviewed = 0;
let sawAuth = 0;
let savedTests = 0;
let scheduleMutations = 0;

async function bodyOf(req) {
  let raw = "";
  for await (const chunk of req) raw += chunk;
  return raw ? JSON.parse(raw) : {};
}

function json(res, status, body) {
  res.writeHead(status, { "Content-Type": "application/json" });
  res.end(JSON.stringify(body));
}

const mock = http.createServer(async (req, res) => {
  const url = new URL(req.url, `http://${req.headers.host}`);
  if (req.headers.authorization === "Bearer jk_contract_test" &&
      req.headers["x-api-key"] === "jk_contract_test" &&
      req.headers["x-account"] === "plugin-test@testers.ai") {
    sawAuth++;
  }
  if (req.method === "POST" && url.pathname === "/api/steer/analyze") {
    const body = await bodyOf(req);
    return json(res, 200, {
      ok: true, id: "plan_1", url: body.url, title: "Checkout",
      features: ["Cart", "Payment"], checks: ["Functionality", "Security"],
      tests: ["Complete checkout"], cap: 20, estimate: { credits: 4 },
    });
  }
  if (req.method === "POST" && url.pathname === "/api/steer/plan_1/submit") {
    return json(res, 200, {
      ok: true,
      reportId: "steered_1",
      viewUrl: "https://reports.testers.ai/r/steered_1",
      credits: 4,
    });
  }
  if (req.method === "POST" && url.pathname === "/api/run-tests") {
    const body = await bodyOf(req);
    if (body.tests?.[0]?.title === "Quota failure") {
      return json(res, 429, { error: "Daily quota reached", code: "daily_quota" });
    }
    return json(res, 200, {
      ok: true, reportId: "target_1", url: "https://example.com",
      viewUrl: "https://reports.testers.ai/rt/target_1",
      results: [
        { kind: "flow", title: "Checkout", passed: false, error: "Pay button did not advance", prompt_to_fix: "Repair the checkout submit handler." },
      ],
    });
  }
  if (req.method === "POST" && url.pathname === "/api/reports") {
    return json(res, 200, {
      created: [{ id: "full_1", url: "https://example.com", viewUrl: "https://reports.testers.ai/r/full_1" }],
    });
  }
  if (req.method === "POST" && url.pathname === "/api/demo-submit") {
    const body = await bodyOf(req);
    if (body.entitlement !== "carbon-plugin-weekly-sampler") {
      return json(res, 400, { error: "missing weekly entitlement" });
    }
    return json(res, 201, {
      reportId: "weekly_1",
      url: body.url,
      viewUrl: "https://reports.testers.ai/r/weekly_1",
      totalPages: 2,
      freeReportsLimit: 1,
      freeReportsRemaining: 0,
      freeReportsWindow: "utc_week",
      freeReportsResetAt: "2026-08-03T00:00:00.000Z",
    });
  }
  if (req.method === "POST" && url.pathname === "/api/chatbot-tests") {
    return json(res, 201, { id: "chat_1", status: "queued", url: "https://example.com/chat" });
  }
  if (req.method === "GET" && url.pathname === "/api/run-tests/target_1") {
    return json(res, 200, {
      ok: true, reportId: "target_1", url: "https://example.com",
      results: [{ kind: "static", title: "No console errors", passed: true }],
    });
  }
  if (req.method === "GET" && url.pathname === "/api/run-tests/full_1") {
    return json(res, 404, { error: "not found" });
  }
  if (req.method === "GET" && url.pathname === "/r/full_1.json") {
    return json(res, 200, {
      id: "full_1", status: "done", url: "https://example.com",
      analysis: {
        score: 78,
        summary: "One checkout defect.",
        issues: [{
          title: "Checkout does not advance",
          severity: "high",
          evidence: "Submit returned no navigation.",
          prompt_to_fix_this_issue: "Repair the checkout submit handler.",
        }],
      },
    });
  }
  if (req.method === "POST" && url.pathname === "/api/reports/full_1/view") {
    reviewed++;
    return json(res, 200, { ok: true });
  }
  if (req.method === "GET" && url.pathname === "/api/reports") {
    return json(res, 200, {
      items: [{ id: "full_1", url: "https://example.com", status: "done", analysis: { score: 78 }, counts: { issues: 1 } }],
    });
  }
  if (req.method === "POST" && url.pathname === "/api/tests/import") {
    return json(res, 201, { created: ["test_1", "test_2"] });
  }
  if (req.method === "POST" && url.pathname === "/api/tests") {
    const body = await bodyOf(req);
    savedTests++;
    if (body.title === "Rejected by service") return json(res, 400, { error: "invalid candidate" });
    return json(res, 201, {
      id: `saved_${savedTests}`,
      title: body.title,
      kind: body.kind,
      status: body.status || "draft",
    });
  }
  if (req.method === "POST" && url.pathname === "/api/schedules") {
    const body = await bodyOf(req);
    scheduleMutations++;
    return json(res, 200, {
      ok: true,
      schedule: {
        id: "sched_1",
        seedReportId: body.reportId,
        label: body.label,
        cadence: body.cadence,
        active: true,
      },
    });
  }
  if (req.method === "GET" && url.pathname === "/api/schedules") {
    return json(res, 200, {
      items: [{
        id: "sched_1",
        seedReportId: "full_1",
        label: "Nightly checkout",
        cadence: { type: "daily", hourUtc: 8, minuteUtc: 30 },
        active: true,
      }],
    });
  }
  if (req.method === "PATCH" && url.pathname === "/api/schedules/sched_1") {
    const body = await bodyOf(req);
    scheduleMutations++;
    return json(res, 200, {
      ok: true,
      schedule: {
        id: "sched_1",
        label: body.label || "Nightly checkout",
        active: body.active ?? true,
        cadence: body.cadence || { type: "daily", hourUtc: 8, minuteUtc: 30 },
      },
    });
  }
  if (req.method === "DELETE" && url.pathname === "/api/schedules/sched_1") {
    scheduleMutations++;
    return json(res, 200, { ok: true });
  }
  return json(res, 404, { error: "mock route not found" });
});

await new Promise((resolve) => mock.listen(0, "127.0.0.1", resolve));
const port = mock.address().port;
const pluginRoot = dirname(dirname(fileURLToPath(import.meta.url)));
const child = spawn(process.execPath, [join(pluginRoot, "server", "index.js")], {
  cwd: pluginRoot,
  env: {
    ...process.env,
    TESTERS_AI_BASE_URL: `http://127.0.0.1:${port}`,
    TESTERS_AI_EMAIL: "plugin-test@testers.ai",
    TESTERS_AI_API_KEY: "jk_contract_test",
    TESTERS_AI_BROWSER_BACKEND: "testers-ai-cloud",
  },
  stdio: ["pipe", "pipe", "pipe"],
});

let buffer = "";
let nextId = 1;
const pending = new Map();
child.stdout.setEncoding("utf8");
child.stdout.on("data", (chunk) => {
  buffer += chunk;
  while (buffer.includes("\n")) {
    const newline = buffer.indexOf("\n");
    const line = buffer.slice(0, newline).trim();
    buffer = buffer.slice(newline + 1);
    if (!line) continue;
    const message = JSON.parse(line);
    const waiter = pending.get(message.id);
    if (waiter) {
      pending.delete(message.id);
      waiter(message.result);
    }
  }
});

function request(method, params = {}) {
  const id = nextId++;
  child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}\n`);
  return new Promise((resolve) => pending.set(id, resolve));
}

function parseTool(result) {
  const text = (result.content || []).map((item) => item.text || "").join("\n");
  const parsed = JSON.parse(text);
  if (result.isError) throw new Error(parsed.error || text);
  return parsed;
}

const timeout = setTimeout(() => {
  console.error("FAIL: cloud contract test timed out");
  child.kill("SIGTERM");
  mock.close();
  process.exit(1);
}, 20_000);

try {
  await request("initialize", { protocolVersion: "2024-11-05", capabilities: {} });

  const browserCapabilities = parseTool(await request("tools/call", {
    name: "carbon_get_browser_capabilities",
    arguments: {},
  }));
  if (
    browserCapabilities.selectedBackend !== "testers-ai-cloud" ||
    browserCapabilities.local.available !== true ||
    browserCapabilities.managed.ready !== true ||
    browserCapabilities.managed.executionTool !== "testers_run_managed_browser"
  ) {
    throw new Error("managed-browser key readiness contract failed");
  }

  const rejectedManagedScope = await request("tools/call", {
    name: "testers_run_managed_browser",
    arguments: {
      scope: "everything",
      url: "https://example.com",
      tests: ["Complete checkout"],
    },
  });
  const rejectedManagedScopeText = (rejectedManagedScope.content || [])
    .map((item) => item.text || "")
    .join("\n");
  if (!rejectedManagedScope.isError || !rejectedManagedScopeText.includes("targeted or full")) {
    throw new Error("managed browser accepted an unknown execution scope");
  }

  const plan = parseTool(await request("tools/call", {
    name: "testers_create_plan",
    arguments: { url: "https://example.com", prompt: "checkout" },
  }));
  if (
    plan.planId !== "plan_1" ||
    plan.features.length !== 2 ||
    plan.steeringWorkspaceUrl !== `http://127.0.0.1:${port}/steer` ||
    !plan.editPlanUrl.endsWith("/steering?id=plan_1")
  ) throw new Error("plan and steering-link contract failed");

  const rejectedPlanRun = await request("tools/call", {
    name: "testers_run_plan",
    arguments: { planId: "plan_1", selection: { features: ["Cart"] } },
  });
  if (!rejectedPlanRun.isError) throw new Error("steering run did not require public-report confirmation");
  const planRun = parseTool(await request("tools/call", {
    name: "testers_run_plan",
    arguments: { planId: "plan_1", selection: { features: ["Cart"] }, confirmPublic: true },
  }));
  if (planRun.reportId !== "steered_1") throw new Error("steering-run contract failed");

  const targeted = parseTool(await request("tools/call", {
    name: "testers_run_targeted",
    arguments: { url: "https://example.com", tests: ["Complete checkout"] },
  }));
  if (targeted.failed !== 1 || !targeted.results[0].promptToFix) throw new Error("targeted-run contract failed");

  const dailyUx = parseTool(await request("tools/call", {
    name: "testers_run_daily_ux",
    arguments: { url: "https://example.com", focus: "checkout" },
  }));
  if (dailyUx.kind !== "daily-ux" || dailyUx.coverage.length !== 5 || dailyUx.failed !== 1) {
    throw new Error("daily targeted UX contract failed");
  }

  const rejectedWeekly = await request("tools/call", {
    name: "testers_run_weekly_sample",
    arguments: { url: "https://example.com" },
  });
  if (!rejectedWeekly.isError) throw new Error("weekly sampler did not require public-report confirmation");
  const weekly = parseTool(await request("tools/call", {
    name: "testers_run_weekly_sample",
    arguments: { url: "https://example.com", confirmPublic: true },
  }));
  if (weekly.reportId !== "weekly_1" || weekly.totalPages !== 2 || weekly.quota.window !== "utc_week") {
    throw new Error("weekly sampler contract failed");
  }

  const managedTargeted = parseTool(await request("tools/call", {
    name: "testers_run_managed_browser",
    arguments: {
      scope: "targeted",
      url: "https://example.com",
      tests: ["Complete checkout"],
    },
  }));
  if (managedTargeted.failed !== 1) throw new Error("managed targeted browser contract failed");

  const rejectedFull = await request("tools/call", {
    name: "testers_run_full",
    arguments: { url: "https://example.com" },
  });
  if (!rejectedFull.isError) throw new Error("full run did not require public-report confirmation");

  const full = parseTool(await request("tools/call", {
    name: "testers_run_full",
    arguments: { url: "https://example.com", confirmPublic: true },
  }));
  if (full.reports[0].reportId !== "full_1") throw new Error("full-run contract failed");

  const managedFull = parseTool(await request("tools/call", {
    name: "testers_run_managed_browser",
    arguments: {
      scope: "full",
      url: "https://example.com",
      confirmPublic: true,
    },
  }));
  if (managedFull.reports[0].reportId !== "full_1") throw new Error("managed full browser contract failed");

  const privateChatbot = parseTool(await request("tools/call", {
    name: "testers_run_chatbot",
    arguments: { url: "https://example.com/chat" },
  }));
  if (privateChatbot.reportId !== "chat_1" || privateChatbot.visibility !== "private") {
    throw new Error("private-by-default chatbot-run contract failed");
  }

  const rejectedPublicChatbot = await request("tools/call", {
    name: "testers_run_chatbot",
    arguments: { url: "https://example.com/chat", visibility: "public" },
  });
  if (!rejectedPublicChatbot.isError) {
    throw new Error("public chatbot run did not require public-report confirmation");
  }

  const publicChatbot = parseTool(await request("tools/call", {
    name: "testers_run_chatbot",
    arguments: {
      url: "https://example.com/chat",
      visibility: "public",
      confirmPublic: true,
    },
  }));
  if (publicChatbot.reportId !== "chat_1" || publicChatbot.visibility !== "public") {
    throw new Error("confirmed public chatbot-run contract failed");
  }

  const targetedResult = parseTool(await request("tools/call", {
    name: "testers_get_results",
    arguments: { reportId: "target_1", kind: "auto" },
  }));
  if (targetedResult.kind !== "targeted" || targetedResult.passed !== 1) throw new Error("targeted-result contract failed");

  const fullResult = parseTool(await request("tools/call", {
    name: "testers_get_results",
    arguments: { reportId: "full_1", kind: "auto" },
  }));
  if (fullResult.score !== 78 || fullResult.issues[0].severity !== "high") throw new Error("full-result contract failed");

  const listed = parseTool(await request("tools/call", {
    name: "testers_list_runs",
    arguments: { limit: 10 },
  }));
  if (listed.items[0].reportId !== "full_1" || listed.items[0].issueCount !== 1) {
    throw new Error("run-history contract failed");
  }

  const rejectedImport = await request("tools/call", {
    name: "testers_import_suite",
    arguments: { host: "example.com", code: "test('checkout', () => {})", language: "playwright", confirm: false },
  });
  if (!rejectedImport.isError) throw new Error("suite import did not require explicit confirmation");

  const imported = parseTool(await request("tools/call", {
    name: "testers_import_suite",
    arguments: { host: "example.com", code: "test('checkout', () => {})", language: "playwright", confirm: true },
  }));
  if (imported.imported !== 2) throw new Error("suite-import contract failed");

  const rejectedSave = await request("tools/call", {
    name: "testers_save_tests",
    arguments: {
      host: "example.com",
      tests: [{ kind: "flow", title: "Checkout", freeformText: "Complete checkout" }],
      confirm: false,
    },
  });
  if (!rejectedSave.isError) throw new Error("candidate test save did not require explicit confirmation");

  const saved = parseTool(await request("tools/call", {
    name: "testers_save_tests",
    arguments: {
      host: "https://example.com/checkout",
      tests: [
        { kind: "flow", title: "Checkout", freeformText: "Complete checkout", source: "carbon-recording", sourceRef: "rec_1" },
        { kind: "static", title: "Rejected by service", assertion: "No console errors" },
        { kind: "static", title: "Missing oracle" },
      ],
      confirm: true,
    },
  }));
  if (
    saved.requested !== 3 ||
    saved.saved !== 1 ||
    saved.failed !== 2 ||
    saved.created[0].id !== "saved_1"
  ) {
    throw new Error("approved candidate save or partial-failure contract failed");
  }

  const rejectedCreateSchedule = await request("tools/call", {
    name: "testers_create_schedule",
    arguments: {
      reportId: "full_1",
      cadence: { type: "daily", hourUtc: 8, minuteUtc: 30 },
      confirm: false,
    },
  });
  if (!rejectedCreateSchedule.isError) throw new Error("schedule creation did not require explicit confirmation");

  const createdSchedule = parseTool(await request("tools/call", {
    name: "testers_create_schedule",
    arguments: {
      reportId: "full_1",
      cadence: { type: "daily", hourUtc: 8, minuteUtc: 30 },
      label: "Nightly checkout",
      confirm: true,
    },
  }));
  if (createdSchedule.schedule?.id !== "sched_1") throw new Error("schedule creation contract failed");

  const schedules = parseTool(await request("tools/call", {
    name: "testers_list_schedules",
    arguments: {},
  }));
  if (schedules.items?.[0]?.id !== "sched_1") throw new Error("schedule list contract failed");

  const rejectedScheduleUpdate = await request("tools/call", {
    name: "testers_update_schedule",
    arguments: { scheduleId: "sched_1", active: false, confirm: false },
  });
  if (!rejectedScheduleUpdate.isError) throw new Error("schedule update did not require explicit confirmation");

  const pausedSchedule = parseTool(await request("tools/call", {
    name: "testers_update_schedule",
    arguments: { scheduleId: "sched_1", active: false, confirm: true },
  }));
  if (pausedSchedule.schedule?.active !== false) throw new Error("schedule pause contract failed");

  const rejectedScheduleDelete = await request("tools/call", {
    name: "testers_delete_schedule",
    arguments: { scheduleId: "sched_1", confirm: false },
  });
  if (!rejectedScheduleDelete.isError) throw new Error("schedule delete did not require explicit confirmation");

  const deletedSchedule = parseTool(await request("tools/call", {
    name: "testers_delete_schedule",
    arguments: { scheduleId: "sched_1", confirm: true },
  }));
  if (deletedSchedule.ok !== true || scheduleMutations !== 3) throw new Error("schedule delete contract failed");

  const quotaFailure = await request("tools/call", {
    name: "testers_run_targeted",
    arguments: {
      url: "https://example.com",
      tests: [{ kind: "flow", title: "Quota failure", freeformText: "Trigger quota response" }],
    },
  });
  const quotaText = (quotaFailure.content || []).map((item) => item.text || "").join("\n");
  if (!quotaFailure.isError || !quotaText.includes('"status": 429') || !quotaText.includes('"code": "daily_quota"')) {
    throw new Error("cloud errors did not preserve status and machine-readable code");
  }

  if (reviewed !== 1) throw new Error("review-tracking contract failed");
  if (sawAuth < 5) throw new Error("authenticated requests did not carry the expected headers");

  console.log("PASS: plan, targeted, managed browser, consent-gated public runs, chatbot, history, results, reviewed-state, auth, approved saved tests with partial failures, suite import, quota errors, and confirmed schedule CRUD contracts verified.");
} catch (error) {
  console.error(`FAIL: ${error.message}`);
  process.exitCode = 1;
} finally {
  clearTimeout(timeout);
  child.kill("SIGTERM");
  await new Promise((resolve) => mock.close(resolve));
}
