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, describe, test } from "vitest";
import { readSwarmDashboardRows } from "../swarm-status";

const roots: string[] = [];

afterEach(() => {
	for (const root of roots.splice(0)) {
		rmSync(root, { recursive: true, force: true });
	}
});

function makeRoot() {
	const root = mkdtempSync(join(tmpdir(), "sf-web-swarms-"));
	roots.push(root);
	return root;
}

function writeProjection(repo: string) {
	mkdirSync(join(repo, ".sf"), { recursive: true });
	writeFileSync(
		join(repo, ".sf", "status.projection.json"),
		JSON.stringify({
			projectionVersion: 1,
			swarmId: repo,
			repoPath: repo,
			repoName: "repo",
			writer: {
				surface: "headless",
				pid: 123,
				writtenAt: "2026-05-17T00:00:00.000Z",
			},
			supervisor: { kind: "headless", health: "running", currentPid: 123 },
			state: {
				activeMilestoneId: "M053",
				activeMilestoneTitle: "Supervisor",
				activeSliceId: "S11",
				activeSliceTitle: "Web projection",
				phase: "planning",
				nextAction: "Plan projection",
				nextUnitType: "plan-slice",
				nextUnitId: "M053/S11",
				queueDepth: 2,
				lastCycleOutcome: "started",
				currentUnit: "plan-slice:M053/S11",
			},
			health: { verdict: "clear", classification: "running", issues: 0 },
		}),
	);
}

describe("readSwarmDashboardRows", () => {
	test("reads_registered_repos_from_status_projection", () => {
		const root = makeRoot();
		const repo = join(root, "repo");
		mkdirSync(repo);
		writeProjection(repo);
		const registry = join(root, "swarms.json");
		writeFileSync(
			registry,
			JSON.stringify({ swarms: [{ name: "Repo", path: repo }] }),
		);

		const rows = readSwarmDashboardRows(registry);

		assert.equal(rows.length, 1);
		assert.equal(rows[0]?.status, "ok");
		assert.equal(rows[0]?.projection?.state.activeMilestoneId, "M053");
	});

	test("missing_projection_degrades_one_repo_without_throwing", () => {
		const root = makeRoot();
		const repo = join(root, "repo");
		mkdirSync(repo);
		const registry = join(root, "swarms.json");
		writeFileSync(registry, JSON.stringify([{ path: repo }]));

		const rows = readSwarmDashboardRows(registry);

		assert.equal(rows.length, 1);
		assert.equal(rows[0]?.status, "missing");
		assert.match(rows[0]?.error ?? "", /projection missing/);
	});
});
