import assert from "node:assert/strict";
import { describe, test } from "vitest";

import {
	ModelRolePolicyValidationError,
	normalizeRolePolicies,
	normalizeRolePolicy,
	validateRolePolicy,
} from "../uok/model-role-policy.js";

describe("model role policy", () => {
	test("normalizeRolePolicy_when_role_has_no_override_returns_auto_policy_with_symbolic_constraints", () => {
		assert.deepEqual(normalizeRolePolicy("worker"), {
			role: "worker",
			mode: "auto",
			constraints: ["coding"],
		});
	});

	test("normalizeRolePolicy_when_constraints_use_alias_casing_returns_canonical_constraint_names", () => {
		assert.deepEqual(
			normalizeRolePolicy("validator", {
				mode: "auto",
				constraints: ["STRICT_JSON", "review", "strict-json"],
			}),
			{
				role: "validator",
				mode: "auto",
				constraints: ["strict-json", "review"],
			},
		);
	});

	test("validateRolePolicy_when_constraint_unknown_returns_clear_validation_error", () => {
		const result = validateRolePolicy("reviewer", {
			mode: "auto",
			constraints: ["review", "vision-model"],
		});

		assert.equal(result.ok, false);
		assert.match(result.errors[0], /unsupported constraint "vision-model"/);
		assert.match(result.errors[0], /coding, review, cheap, long-context/);
		assert.equal(result.policy, null);
	});

	test("normalizeRolePolicy_when_policy_contains_concrete_model_id_rejects_durable_route_config", () => {
		assert.throws(
			() =>
				normalizeRolePolicy("orchestrator", {
					mode: "auto",
					modelId: "concrete-route",
				}),
			(error) => {
				assert.equal(error instanceof ModelRolePolicyValidationError, true);
				assert.match(error.message, /durable policy cannot include "modelId"/);
				return true;
			},
		);
	});

	test("normalizeRolePolicy_when_mode_is_concrete_model_rejects_non_auto_intent", () => {
		assert.throws(
			() => normalizeRolePolicy("worker", { model: "concrete-route" }),
			/must use mode "auto"/,
		);
	});

	test("normalizeRolePolicies_when_partial_policy_supplied_projects_all_supported_roles", () => {
		assert.deepEqual(
			normalizeRolePolicies({
				Reviewer: { mode: "auto", constraints: ["cheap", "review"] },
			}),
			{
				orchestrator: {
					role: "orchestrator",
					mode: "auto",
					constraints: ["long-context", "strict-json"],
				},
				worker: {
					role: "worker",
					mode: "auto",
					constraints: ["coding"],
				},
				validator: {
					role: "validator",
					mode: "auto",
					constraints: ["strict-json", "review"],
				},
				reviewer: {
					role: "reviewer",
					mode: "auto",
					constraints: ["cheap", "review"],
				},
			},
		);
	});

	test("normalizeRolePolicies_when_role_unknown_rejects_projection", () => {
		assert.throws(
			() => normalizeRolePolicies({ planner: { mode: "auto" } }),
			/unsupported model role "planner"/,
		);
	});
});
