/**
 * unit-handoff.test.mjs - unit closeout schema contracts.
 *
 * Purpose: prove SF preserves useful Droid handoff fields as validated
 * structured data that follow-on autonomous units can trust.
 */

import assert from "node:assert/strict";
import { test } from "vitest";
import {
	normalizeUnitHandoff,
	validateUnitHandoff,
} from "../uok/unit-handoff.js";

test("normalizeUnitHandoff_when_payload_has_droid_closeout_fields_returns_canonical_contract", () => {
	const handoff = normalizeUnitHandoff({
		summary: "  Added unit handoff schema.  ",
		filesChanged: [" src/resources/extensions/sf/uok/unit-handoff.js "],
		testsAdded: [" src/resources/extensions/sf/tests/unit-handoff.test.mjs "],
		commandsRun: [
			{
				command: " npm run test:unit -- unit-handoff.test.mjs ",
				status: "passed",
				exitCode: 0,
				cwd: " /repo ",
				notes: " focused schema test ",
				durationMs: 124,
			},
		],
		knownFailures: [" none "],
		leftUndone: [" wire into finalizer later "],
		fulfilledAssertions: [" malformed commands are rejected "],
		verificationStatus: "passed",
	});

	assert.deepEqual(handoff, {
		summary: "Added unit handoff schema.",
		filesChanged: ["src/resources/extensions/sf/uok/unit-handoff.js"],
		testsAdded: ["src/resources/extensions/sf/tests/unit-handoff.test.mjs"],
		commandsRun: [
			{
				command: "npm run test:unit -- unit-handoff.test.mjs",
				status: "passed",
				exitCode: 0,
				cwd: "/repo",
				notes: "focused schema test",
				durationMs: 124,
			},
		],
		knownFailures: ["none"],
		leftUndone: ["wire into finalizer later"],
		fulfilledAssertions: ["malformed commands are rejected"],
		verificationStatus: "passed",
	});
});

test("normalizeUnitHandoff_when_optional_fields_missing_returns_empty_arrays_and_unknown_status", () => {
	assert.deepEqual(normalizeUnitHandoff({ summary: "No changes needed." }), {
		summary: "No changes needed.",
		filesChanged: [],
		testsAdded: [],
		commandsRun: [],
		knownFailures: [],
		leftUndone: [],
		fulfilledAssertions: [],
		verificationStatus: "unknown",
	});
});

test("validateUnitHandoff_when_array_field_is_not_array_reports_clear_field_error", () => {
	const result = validateUnitHandoff({
		summary: "Bad handoff.",
		filesChanged: "src/file.js",
		testsAdded: [],
		commandsRun: [],
		knownFailures: [],
		leftUndone: [],
		fulfilledAssertions: [],
		verificationStatus: "failed",
	});

	assert.equal(result.ok, false);
	assert.deepEqual(result.errors, ["filesChanged must be an array"]);
});

test("normalizeUnitHandoff_when_command_entry_is_malformed_rejects_with_command_path", () => {
	assert.throws(
		() =>
			normalizeUnitHandoff({
				summary: "Bad command.",
				commandsRun: [{ status: "passed", exitCode: 0 }],
			}),
		/Invalid unit handoff: commandsRun\[0\]\.command must be a non-empty string/,
	);
});

test("validateUnitHandoff_when_command_entry_has_invalid_status_and_exit_code_reports_both_errors", () => {
	const result = validateUnitHandoff({
		commandsRun: [{ command: "npm test", status: "green", exitCode: -1 }],
	});

	assert.equal(result.ok, false);
	assert.deepEqual(result.errors, [
		"commandsRun[0].status must be one of passed, failed, skipped, not-run, unknown",
		"commandsRun[0].exitCode must be a non-negative integer",
	]);
});
