#!/usr/bin/env node
// Generate a markdown + json snapshot of the provider capability matrix from
// the compiled per-provider manifests in `dist/migrate/providers/`.
// Pure dev-tool: artifacts land in `tmp/` (gitignored). Not run in CI.
//
// Usage: node scripts/build-provider-capability-matrix.mjs [--out <dir>]
// Requires `npm run build` to have produced `dist/` first.

import { mkdirSync, writeFileSync, existsSync } from "node:fs";
import { homedir } from "node:os";
import { join, resolve } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = fileURLToPath(new URL(".", import.meta.url));
const pkgRoot = resolve(__dirname, "..");

const args = process.argv.slice(2);
const outIdx = args.indexOf("--out");
const outDir = outIdx >= 0 && args[outIdx + 1] ? resolve(args[outIdx + 1]) : join(pkgRoot, "tmp");

const distEntry = join(pkgRoot, "dist", "migrate", "providers", "index.js");
if (!existsSync(distEntry)) {
	console.error(`[capability-matrix] missing ${distEntry} — run 'npm run build' first.`);
	process.exit(2);
}

const { manifestRegistry } = await import(distEntry);

const SURFACE_FIELDS = ["agent", "command", "skill", "config", "rules", "hooks"];
const STATUS_GLYPH = {
	documented: "OK documented",
	partial: "~ partial",
	unsupported: "X unsupported",
};

const payload = {
	lastVerified: manifestRegistry[0]?.contract?.lastVerified ?? null,
	providers: {},
};

for (const m of manifestRegistry) {
	const c = m.config;
	const ct = m.contract;
	const surfaces = {};
	for (const s of SURFACE_FIELDS) {
		surfaces[s] = ct.surfaces[s]?.status ?? "unsupported";
	}
	const capabilities = {};
	for (const [name, contract] of Object.entries(ct.capabilities)) {
		capabilities[name] = contract.status;
	}
	payload.providers[m.id] = {
		displayName: c.displayName,
		supportLevel: c.supportLevel ?? "verified",
		supportReason: c.supportReason ?? null,
		subagents: c.subagents,
		surfaces,
		capabilities,
		docs: ct.docs,
		lastVerified: ct.lastVerified,
	};
}

// Path-leak guard: ensure no filesystem paths from the dev machine sneaked
// into the serialized output. We never spread `config` directly, but a defensive
// assertion catches accidents from future edits.
const serialized = JSON.stringify(payload);
if (serialized.includes(homedir())) {
	console.error("[capability-matrix] aborting — output contains homedir() path");
	process.exit(3);
}

mkdirSync(outDir, { recursive: true });
const jsonPath = join(outDir, "provider-capability-matrix.json");
writeFileSync(jsonPath, JSON.stringify(payload, null, 2) + "\n");

const md = renderMarkdown(payload);
const mdPath = join(outDir, "provider-capability-matrix.md");
writeFileSync(mdPath, md);

console.log(`[capability-matrix] wrote ${mdPath}`);
console.log(`[capability-matrix] wrote ${jsonPath}`);

function renderMarkdown(p) {
	const lines = [];
	lines.push("<!-- AUTOGENERATED by scripts/build-provider-capability-matrix.mjs — do not edit, do not commit -->");
	lines.push("# Provider Capability Matrix");
	if (p.lastVerified) lines.push(`_Last verified: ${p.lastVerified}_`);
	lines.push("");

	lines.push("## Surface support (per provider x portable type)");
	lines.push("| Provider | Agent | Command | Skill | Config | Rules | Hooks |");
	lines.push("| --- | --- | --- | --- | --- | --- | --- |");
	for (const [id, data] of Object.entries(p.providers)) {
		const row = [id];
		for (const s of SURFACE_FIELDS) {
			row.push(STATUS_GLYPH[data.surfaces[s]] ?? data.surfaces[s]);
		}
		lines.push(`| ${row.join(" | ")} |`);
	}
	lines.push("");

	lines.push("## Detailed per-provider entries");
	for (const [id, data] of Object.entries(p.providers)) {
		lines.push(`### ${id} (${data.supportLevel})`);
		if (data.supportReason) lines.push(`- supportReason: "${data.supportReason}"`);
		lines.push(`- Subagents: ${data.subagents}`);
		const surfaceLine = SURFACE_FIELDS.map((s) => `${s}: ${STATUS_GLYPH[data.surfaces[s]] ?? data.surfaces[s]}`).join(" | ");
		lines.push(`- Surfaces: ${surfaceLine}`);
		const capLines = Object.entries(data.capabilities)
			.map(([name, status]) => `  - ${name}: ${STATUS_GLYPH[status] ?? status}`)
			.join("\n");
		lines.push("- Capabilities:");
		lines.push(capLines);
		lines.push(`- Docs: ${data.docs.join(" | ")}`);
		lines.push("");
	}
	return lines.join("\n");
}
