import assert from "node:assert/strict";
import { test } from "vitest";
import {
	buildWorkerContextPackProjection,
	validateWorkerContextPackProjection,
} from "../uok/context-pack-projection.js";

test("buildProjection_when_contract_has_worker_context_returns_droid_sections", () => {
	const projection = buildWorkerContextPackProjection({
		milestoneId: "M001",
		sliceId: "S01",
		taskId: "T01",
		unitId: "M001/S01/T01",
		unitType: "execute-task",
		purpose: "Protect worker dispatch context.",
		consumer: "Autonomous worker prompt adapter.",
		preconditions: ["DB dispatch preview selected this task."],
		expectedBehavior: ["Worker receives bounded context."],
		verificationSteps: ["Run focused projection tests."],
		fulfills: ["REQ-worker-context-pack"],
		assertionIds: ["ASSERT-db-remains-canonical"],
		allowedCommands: ["npm run test:unit"],
		allowedServices: ["git"],
		workerSkill: {
			id: "worker-context",
			name: "Worker Context",
			instructions: ["Use projected context as read-only prompt input."],
		},
		library: {
			references: ["docs/specs/sf-operating-model.md"],
			files: ["src/resources/extensions/sf/uok/context-pack-projection.js"],
			assumptions: ["Runtime wiring happens later."],
		},
	});

	assert.equal(projection.origin, "worker-context-pack-projection");
	assert.equal(projection.canonicalState.source, "sf-db");
	assert.equal(projection.canonicalState.projectionOnly, true);
	assert.deepEqual(
		Object.keys(projection).filter((key) =>
			[
				"services",
				"validationContract",
				"unitContract",
				"workerSkill",
				"library",
			].includes(key),
		),
		[
			"services",
			"validationContract",
			"unitContract",
			"workerSkill",
			"library",
		],
	);
	assert.deepEqual(projection.services.allowedCommands, ["npm run test:unit"]);
	assert.deepEqual(projection.services.allowedServices, ["git"]);
	assert.deepEqual(projection.validationContract.preconditions, [
		"DB dispatch preview selected this task.",
	]);
	assert.deepEqual(projection.validationContract.expectedBehavior, [
		"Worker receives bounded context.",
	]);
	assert.deepEqual(projection.validationContract.verificationSteps, [
		"Run focused projection tests.",
	]);
	assert.deepEqual(projection.validationContract.fulfills, [
		"REQ-worker-context-pack",
	]);
	assert.deepEqual(projection.validationContract.assertionIds, [
		"ASSERT-db-remains-canonical",
	]);
	assert.equal(
		projection.unitContract.purpose,
		"Protect worker dispatch context.",
	);
	assert.equal(projection.workerSkill.id, "worker-context");
	assert.deepEqual(projection.library.references, [
		"docs/specs/sf-operating-model.md",
	]);
});

test("buildProjection_when_contract_uses_nested_sections_preserves_allowed_surfaces", () => {
	const projection = buildWorkerContextPackProjection({
		validationContract: {
			preconditions: "Canonical DB unit exists.",
			expectedBehavior: "Projection contains prompt-safe shape.",
			verificationSteps: "Validate the pack before rendering.",
			assertionIds: ["ASSERT-shape"],
		},
		unitContract: {
			unitId: "M010/S02/T03",
			unitType: "feature-contract",
			fulfills: ["REQ-context"],
		},
		services: {
			allowedCommands: ["npm test", "npm test"],
			allowedServices: ["sqlite", "git"],
		},
		workerSkill: {
			allowedCommands: ["npx vitest run"],
			allowedServices: ["sqlite"],
		},
	});

	assert.deepEqual(projection.services.allowedCommands, [
		"npm test",
		"npx vitest run",
	]);
	assert.deepEqual(projection.services.allowedServices, ["sqlite", "git"]);
	assert.deepEqual(projection.validationContract.preconditions, [
		"Canonical DB unit exists.",
	]);
	assert.deepEqual(projection.validationContract.assertionIds, [
		"ASSERT-shape",
	]);
	assert.deepEqual(projection.validationContract.fulfills, ["REQ-context"]);
	assert.equal(projection.unitRef.unitId, "M010/S02/T03");
	assert.equal(projection.unitRef.unitType, "feature-contract");
});

test("buildProjection_when_optional_fields_missing_returns_empty_arrays_not_runtime_reads", () => {
	const projection = buildWorkerContextPackProjection({
		unitId: "M001/S01/T99",
	});

	assert.deepEqual(projection.services.allowedCommands, []);
	assert.deepEqual(projection.services.allowedServices, []);
	assert.deepEqual(projection.validationContract.preconditions, []);
	assert.deepEqual(projection.validationContract.expectedBehavior, []);
	assert.deepEqual(projection.validationContract.verificationSteps, []);
	assert.deepEqual(projection.library.files, []);
	assert.match(projection.canonicalState.note, /projection only/);
	assert.equal(validateWorkerContextPackProjection(projection).valid, true);
});

test("validateProjection_when_required_section_missing_reports_invalid_projection", () => {
	const projection = buildWorkerContextPackProjection({
		preconditions: ["DB unit exists."],
	});
	delete projection.validationContract;

	const result = validateWorkerContextPackProjection(projection);

	assert.equal(result.valid, false);
	assert.ok(result.issues.includes("validationContract section is required"));
});

test("validateProjection_when_array_fields_are_not_arrays_reports_field_issue", () => {
	const projection = buildWorkerContextPackProjection({
		allowedCommands: ["npm run test:unit"],
	});
	projection.services.allowedCommands = "npm run test:unit";

	const result = validateWorkerContextPackProjection(projection);

	assert.equal(result.valid, false);
	assert.ok(
		result.issues.includes("services.allowedCommands must be an array"),
	);
});
