/**
 * doctor-task-plan-id-drift.test.mjs - task plan ID drift repair.
 *
 * Purpose: prove doctor repairs the single-task DB/disk mismatch that makes
 * autonomous redispatch plan-slice instead of executing the active task.
 */
import assert from "node:assert/strict";
import {
	existsSync,
	mkdirSync,
	mkdtempSync,
	rmSync,
	writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, test } from "vitest";
import { runSFDoctor } from "../doctor.js";
import {
	closeDatabase,
	insertMilestone,
	insertSlice,
	insertTask,
	openDatabase,
} from "../sf-db.js";

const tmpDirs = [];

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

function makeProject() {
	const dir = mkdtempSync(join(tmpdir(), "sf-doctor-task-plan-drift-"));
	tmpDirs.push(dir);
	mkdirSync(join(dir, ".sf", "milestones", "M910", "slices", "S07", "tasks"), {
		recursive: true,
	});
	openDatabase(join(dir, ".sf", "sf.db"));
	insertMilestone({
		id: "M910",
		title: "Task plan drift",
		status: "active",
		planning: {
			vision: "Repair task plan ID drift.",
			successCriteria: ["Active task plan can be dispatched."],
		},
	});
	insertSlice({
		milestoneId: "M910",
		id: "S07",
		title: "Tie back",
		status: "active",
		risk: "low",
		depends: [],
		demo: "Single task executes.",
		sequence: 1,
	});
	insertTask({
		milestoneId: "M910",
		sliceId: "S07",
		id: "T07.1",
		title: "Replace backlog with schedule",
		status: "pending",
		sequence: 1,
	});
	writeFileSync(
		join(dir, ".sf", "milestones", "M910", "M910-ROADMAP.md"),
		"# M910: Task plan drift\n\n## S07: Tie back\n",
	);
	writeFileSync(
		join(dir, ".sf", "milestones", "M910", "slices", "S07", "S07-PLAN.md"),
		"# S07: Tie back\n\n## Tasks\n\n- [ ] T07.1: Replace backlog with schedule\n",
	);
	writeFileSync(
		join(
			dir,
			".sf",
			"milestones",
			"M910",
			"slices",
			"S07",
			"tasks",
			"T01-PLAN.md",
		),
		"# T07.1: Replace backlog with schedule\n",
	);
	return dir;
}

describe("doctor task plan ID drift", () => {
	test("runSFDoctor_fix_copies_single_orphan_plan_to_active_db_task_id", async () => {
		const project = makeProject();
		const expected = join(
			project,
			".sf",
			"milestones",
			"M910",
			"slices",
			"S07",
			"tasks",
			"T07.1-PLAN.md",
		);

		const report = await runSFDoctor(project, {
			fix: true,
			fixLevel: "all",
		});

		assert.equal(
			report.issues.some((issue) => issue.code === "task_plan_id_drift"),
			true,
		);
		assert.equal(existsSync(expected), true);
		assert.ok(
			report.fixesApplied.includes(
				"copied T01-PLAN.md to T07.1-PLAN.md for M910/S07",
			),
		);
	});
});
