/**
 * Schedule Kind Synchronisation — tooling test.
 *
 * Purpose: verify that every schedule kind mentioned in prompts and documentation
 * is present in VALID_KINDS (the single source of truth in schedule-types.js).
 * Catches drift where a prompt documents a kind that is silently rejected by
 * isValidKind().
 *
 * Consumer: CI test runner (vitest). Run via `npm test`.
 */
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { join } from "node:path";
import { describe, it } from "vitest";
import { ALL_SCHEDULE_KINDS, VALID_KINDS } from "../schedule/schedule-types.js";

// Files that document or schema-validate ScheduleSpec.kind.
const TRACKED_FILES = [
	join(import.meta.dirname, "../prompts/plan-milestone.md"),
	join(import.meta.dirname, "../prompts/guided-plan-milestone.md"),
	join(import.meta.dirname, "../bootstrap/db-tools.js"),
];

/**
 * Extract all double-quoted strings that look like schedule kinds from a file.
 * Matches patterns like kind: "review" or 'review' in YAML/markdown context.
 *
 * @param {string} content
 * @returns {string[]}
 */
function extractKindLiterals(content) {
	const found = new Set();
	const re = /(?:kind\s*[:=]\s*["'])([a-z_]+)["']/gi;
	let match;
	while ((match = re.exec(content)) !== null) {
		found.add(match[1].toLowerCase());
	}

	return [...found];
}

describe("schedule-kinds sync", () => {
	describe("VALID_KINDS and ALL_SCHEDULE_KINDS", () => {
		it("ALL_SCHEDULE_KINDS is a non-empty array", () => {
			assert.ok(Array.isArray(ALL_SCHEDULE_KINDS));
			assert.ok(ALL_SCHEDULE_KINDS.length > 0);
		});

		it("ALL_SCHEDULE_KINDS matches VALID_KINDS contents", () => {
			assert.deepEqual(ALL_SCHEDULE_KINDS.sort(), [...VALID_KINDS].sort());
		});

		it("every ALL_SCHEDULE_KINDS entry is a non-empty string", () => {
			for (const k of ALL_SCHEDULE_KINDS) {
				assert.equal(typeof k, "string");
				assert.ok(k.length > 0, `empty kind in ALL_SCHEDULE_KINDS`);
			}
		});

		it("VALID_KINDS has no duplicate entries", () => {
			const seen = new Set();
			for (const k of VALID_KINDS) {
				assert.ok(!seen.has(k), `duplicate kind: ${k}`);
				seen.add(k);
			}
		});
	});

	describe("prompt kind references are in VALID_KINDS", () => {
		for (const filePath of TRACKED_FILES) {
			const content = readFileSync(filePath, "utf-8");
			const mentioned = extractKindLiterals(content);

			if (mentioned.length === 0) {
				// No kind references found — skip but report
				it(`${filePath.split("/").pop()}: finds no kind literals (add to TRACKED_FILES or remove from list)`, () => {
					// pass — file may genuinely have no kind references
				});
				continue;
			}

			for (const kind of mentioned) {
				it(`${filePath.split("/").pop()}: kind "${kind}" is in VALID_KINDS`, () => {
					assert.ok(
						VALID_KINDS.has(kind),
						`"${kind}" is mentioned in ${filePath.split("/").pop()} ` +
							`but is not in VALID_KINDS (${[...VALID_KINDS].join(", ")})`,
					);
				});
			}
		}
	});

	describe("VALID_KINDS has documented SF schedule system kinds", () => {
		it('has "review" kind', () => {
			assert.ok(
				VALID_KINDS.has("review"),
				"review kind missing from VALID_KINDS",
			);
		});

		it('has "audit" kind', () => {
			assert.ok(
				VALID_KINDS.has("audit"),
				"audit kind missing from VALID_KINDS",
			);
		});

		it('has "command" kind', () => {
			assert.ok(
				VALID_KINDS.has("command"),
				"command kind missing from VALID_KINDS",
			);
		});
	});
});
