/**
 * milestone-validation-db-authority.test.mjs — validation verdict source of truth.
 *
 * Purpose: prove DB-backed projects derive milestone validation phase from the
 * structured assessment row, with VALIDATION.md only used when DB is unavailable.
 */
import assert from "node:assert/strict";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, test } from "vitest";
import {
	closeDatabase,
	insertAssessment,
	insertMilestone,
	insertSlice,
	openDatabase,
} from "../sf-db.js";
import { deriveState, invalidateStateCache } from "../state.js";

const tmpDirs = [];

afterEach(() => {
	closeDatabase();
	invalidateStateCache();
	while (tmpDirs.length > 0) {
		const dir = tmpDirs.pop();
		if (dir) rmSync(dir, { recursive: true, force: true });
	}
});

function makeProject() {
	const dir = mkdtempSync(join(tmpdir(), "sf-validation-db-authority-"));
	tmpDirs.push(dir);
	mkdirSync(join(dir, ".sf", "milestones", "M001"), { recursive: true });
	openDatabase(join(dir, ".sf", "sf.db"));
	insertMilestone({
		id: "M001",
		title: "Validation DB authority",
		status: "active",
	});
	insertSlice({
		milestoneId: "M001",
		id: "S01",
		title: "Done slice",
		status: "complete",
		sequence: 1,
	});
	writeFileSync(
		join(dir, ".sf", "milestones", "M001", "M001-ROADMAP.md"),
		[
			"# M001: Validation DB authority",
			"",
			"## Slice Overview",
			"| ID | Slice | Risk | Depends | Done | After this |",
			"|----|-------|------|---------|------|------------|",
			"| S01 | Done slice | low | - | ✅ | done |",
			"",
		].join("\n"),
	);
	return dir;
}

test("deriveState_when_db_validation_pass_and_file_stale_completes_validation_phase", async () => {
	const project = makeProject();
	const validationPath = join(
		project,
		".sf",
		"milestones",
		"M001",
		"M001-VALIDATION.md",
	);
	writeFileSync(
		validationPath,
		[
			"---",
			"verdict: needs-remediation",
			"remediation_round: 1",
			"---",
			"",
			"# stale validation projection",
			"",
		].join("\n"),
	);
	insertAssessment({
		path: validationPath,
		milestoneId: "M001",
		status: "pass",
		scope: "milestone-validation",
		fullContent: [
			"---",
			"verdict: pass",
			"remediation_round: 2",
			"---",
			"",
			"# DB validation pass",
			"",
		].join("\n"),
	});

	const state = await deriveState(project);

	assert.equal(state.phase, "completing-milestone");
	assert.equal(state.activeMilestone?.id, "M001");
});

test("deriveState_when_db_validation_missing_and_file_has_verdict_requires_db_assessment", async () => {
	const project = makeProject();
	const validationPath = join(
		project,
		".sf",
		"milestones",
		"M001",
		"M001-VALIDATION.md",
	);
	writeFileSync(
		validationPath,
		[
			"---",
			"verdict: pass",
			"---",
			"",
			"# stale validation projection",
			"",
		].join("\n"),
	);

	const state = await deriveState(project);

	assert.equal(state.phase, "validating-milestone");
	assert.equal(state.activeMilestone?.id, "M001");
});
