import assert from "node:assert/strict";
import {
	existsSync,
	mkdirSync,
	mkdtempSync,
	rmSync,
	writeFileSync,
} from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join } from "node:path";
import { afterEach, describe, test } from "vitest";
import { runSFDoctor } from "../doctor.js";
import { stampScaffoldFile } from "../scaffold-versioning.js";

const tmpDirs = [];

afterEach(() => {
	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-generated-"));
	tmpDirs.push(dir);
	mkdirSync(join(dir, ".sf"), { recursive: true });
	return dir;
}

function writeOwnedLegacyHarnessFile(root, relPath) {
	const target = join(root, relPath);
	mkdirSync(dirname(target), { recursive: true });
	writeFileSync(target, `# ${relPath}\n`, "utf-8");
	stampScaffoldFile(target, relPath, "2.75.0", "pending");
}

describe("doctor generated artifact hygiene", () => {
	test("runSFDoctor_reports_sf_owned_root_harness_residue", async () => {
		const project = makeProject();
		writeOwnedLegacyHarnessFile(project, "harness/specs/bootstrap.md");

		const report = await runSFDoctor(project, { scope: "project" });

		const issue = report.issues.find(
			(i) => i.code === "generated_root_harness_residue",
		);
		assert.equal(issue?.fixable, true);
		assert.equal(existsSync(join(project, "harness/specs/bootstrap.md")), true);
	});

	test("runSFDoctor_fix_removes_only_sf_owned_pending_root_harness", async () => {
		const project = makeProject();
		writeOwnedLegacyHarnessFile(project, "harness/specs/bootstrap.md");

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

		assert.ok(
			report.fixesApplied.includes("removed 1 SF-owned root harness file(s)"),
		);
		assert.equal(existsSync(join(project, "harness")), false);
	});

	test("runSFDoctor_ignores_user_owned_root_harness", async () => {
		const project = makeProject();
		mkdirSync(join(project, "harness/specs"), { recursive: true });
		writeFileSync(
			join(project, "harness/specs/project-contract.md"),
			"# Project-owned harness\n",
		);

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

		assert.equal(
			report.issues.some((i) => i.code === "generated_root_harness_residue"),
			false,
		);
		assert.equal(
			existsSync(join(project, "harness/specs/project-contract.md")),
			true,
		);
	});
});
