#!/usr/bin/env node
/** Verify CARBON dispatches and syncs only with the self-hosted feedback service. */

import { spawn } from "node:child_process";
import fs from "node:fs";
import http from "node:http";
import os from "node:os";
import path from "node:path";
import readline from "node:readline";
import { fileURLToPath } from "node:url";

const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const temporary = fs.mkdtempSync(path.join(os.tmpdir(), "carbon-feedback-private-"));
const servicePort = await new Promise((resolve) => {
  const probe = http.createServer();
  probe.listen(0, "127.0.0.1", () => { const port = probe.address().port; probe.close(() => resolve(port)); });
});
const base = `http://127.0.0.1:${servicePort}`;
const service = spawn(process.execPath, ["feedback-service/server.mjs"], {
  cwd: root,
  env: { ...process.env, CARBON_FEEDBACK_DEV: "true", PORT: String(servicePort), CARBON_FEEDBACK_PUBLIC_URL: base, CARBON_FEEDBACK_DATA_FILE: path.join(temporary, "service.json") },
  stdio: ["ignore", "ignore", "pipe"],
});
const mcp = spawn(process.execPath, ["bin/carbon-mcp.mjs"], { cwd: root, stdio: ["pipe", "pipe", "pipe"] });
let stderr = "";
mcp.stderr.on("data", (chunk) => { stderr += String(chunk); });
const lines = readline.createInterface({ input: mcp.stdout });
let nextId = 0;
const pending = new Map();
lines.on("line", (line) => { try { const message = JSON.parse(line); const resolve = pending.get(message.id); if (resolve) { pending.delete(message.id); resolve(message); } } catch {} });
function request(method, params) { const id = ++nextId; return new Promise((resolve, reject) => { const timer = setTimeout(() => { pending.delete(id); reject(new Error(`Timed out waiting for ${method}: ${stderr}`)); }, 10_000); pending.set(id, (result) => { clearTimeout(timer); resolve(result); }); mcp.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", id, method, params })}\n`); }); }
function payload(message) { const text = message.result?.content?.find((item) => item.type === "text")?.text; if (!text) throw new Error("MCP response has no text payload."); return JSON.parse(text); }
async function ready() { for (let index = 0; index < 40; index += 1) { try { if ((await fetch(`${base}/missing`)).status === 404) return; } catch {} await new Promise((resolve) => setTimeout(resolve, 50)); } throw new Error("Private Feedback Service did not start."); }

try {
  await ready();
  await request("initialize", { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "feedback-private-contract", version: "1" } });
  const project = fs.mkdtempSync(path.join(temporary, "project-"));
  fs.writeFileSync(path.join(project, "package.json"), JSON.stringify({ name: "private-feedback-contract" }));
  const created = payload(await request("tools/call", { name: "carbon_feedback_context", arguments: { action: "create", root: project, title: "Checkout review", focus: "Does this feel trustworthy to a first-time customer?", artifact: "https://example.test/checkout", artifactKind: "url", recipientEmail: "reviewer@example.test", privateServiceUrl: base, privateServiceKey: "local-contract-key", privateServiceConfirmed: true } }));
  if (created.request?.delivery?.mode !== "private-service" || !created.request?.delivery?.serviceReviewId || !created.request?.delivery?.reviewerUrl) throw new Error("CARBON did not record private service dispatch state.");
  const reviewer = new URL(created.request.delivery.reviewerUrl);
  const feedback = await fetch(`${base}/v1/reviews/${encodeURIComponent(created.request.delivery.serviceReviewId)}`, { method: "POST", headers: { "Content-Type": "application/json", "X-Carbon-Feedback-Token": reviewer.hash.slice(1) }, body: JSON.stringify({ rating: 4, category: "trust", response: "Clear total; add reassurance before final confirmation." }) });
  if (feedback.status !== 201) throw new Error(`Private reviewer response failed: ${feedback.status}`);
  const synced = payload(await request("tools/call", { name: "carbon_feedback_context", arguments: { action: "sync", root: project, requestId: created.request.id, privateServiceUrl: base, privateServiceKey: "local-contract-key", privateServiceConfirmed: true } }));
  if (synced.importedResponses?.length !== 1 || synced.importedResponses[0].source !== "private-feedback-service") throw new Error("CARBON did not import the scoped reviewer response.");
  console.log("PASS: CARBON private Feedback Service dispatch → reviewer capability → response → explicit project-local sync");
} finally {
  mcp.kill("SIGTERM"); service.kill("SIGTERM"); lines.close();
}
