#!/usr/bin/env node
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const root = path.join(__dirname, "..");

const REQUIRED_TOP = [
  "schema_version",
  "resolver_order",
  "fallback_policy",
  "execution_policy_defaults",
  "clarification_policy",
  "classification",
  "task_types"
];

const MEMORY_LEVELS = new Set(["none", "optional", "required"]);
const WEIGHTS = new Set(["light", "medium", "heavy"]);
const PLANS = new Set(["auto", "confirm", "override"]);

function fail(msg) {
  console.error(`matrix validation error: ${msg}`);
  process.exit(1);
}

function validateMatrix(matrix) {
  if (!matrix || typeof matrix !== "object") fail("root must be object");

  for (const key of REQUIRED_TOP) {
    if (!(key in matrix)) fail(`missing top-level key: ${key}`);
  }

  const semver = String(matrix.schema_version || "");
  if (!/^\d+\.\d+$/.test(semver)) fail("schema_version must be major.minor (e.g. 1.1)");

  const ids = new Set();
  for (const tt of matrix.task_types) {
    if (!tt.id) fail("task_types entry missing id");
    if (ids.has(tt.id)) fail(`duplicate task_type id: ${tt.id}`);
    ids.add(tt.id);
    if (!tt.capability) fail(`task_type ${tt.id} missing capability`);
    if (!Array.isArray(tt.keywords)) fail(`task_type ${tt.id} keywords must be array`);
    if (tt.requires_memory && !MEMORY_LEVELS.has(tt.requires_memory)) {
      fail(`task_type ${tt.id} invalid requires_memory`);
    }
    if (tt.weight_default && !WEIGHTS.has(tt.weight_default)) {
      fail(`task_type ${tt.id} invalid weight_default`);
    }
    if (tt.default_execution_policy && !PLANS.has(tt.default_execution_policy)) {
      fail(`task_type ${tt.id} invalid default_execution_policy`);
    }
    for (const p of tt.providers || []) {
      if (!p.name || !p.type || !p.resource) {
        fail(`task_type ${tt.id} provider missing name/type/resource`);
      }
    }
  }

  const policy = matrix.provider_activation_policy;
  if (policy) {
    for (const kind of ["memory_providers", "graph_providers"]) {
      const block = policy[kind];
      if (!block) continue;
      if (block.default !== "off" && block.default !== "on") {
        fail(`${kind}.default must be off|on`);
      }
    }
  }

  for (const chain of matrix.capability_chains || []) {
    if (!chain.from_capability || !chain.then_capability) {
      fail("capability_chains entry needs from_capability and then_capability");
    }
  }

  console.log(`matrix valid (schema_version ${matrix.schema_version}, ${matrix.task_types.length} task_types)`);
}

const matrixPath = process.argv[2] || path.join(root, "skill-routing-matrix.json");
if (!fs.existsSync(matrixPath)) fail(`file not found: ${matrixPath}`);
validateMatrix(JSON.parse(fs.readFileSync(matrixPath, "utf-8")));
