// Tests for ci_monitor.cjs — cross-platform CI monitoring tool
//
// Sections:
//   (a) Script exists and is executable
//   (b) --help shows all commands
//   (c) list-workflows finds workflow files
//   (d) check-actions parses actions from workflow
//   (e) Commands validate required arguments

import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { existsSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { describe, it } from "vitest";

const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dirname, "..", "..", "..");
const SCRIPT_PATH = join(ROOT, "scripts", "ci_monitor.cjs");

function runScript(args: string[]): {
	stdout: string;
	stderr: string;
	status: number | null;
} {
	const result = spawnSync("node", [SCRIPT_PATH, ...args], {
		encoding: "utf-8",
		timeout: 30000,
	});
	return {
		stdout: result.stdout || "",
		stderr: result.stderr || "",
		status: result.status,
	};
}

describe("ci_monitor.cjs", () => {
	it("script exists and has valid JavaScript syntax", () => {
		assert.ok(existsSync(SCRIPT_PATH), "ci_monitor.cjs exists");
		const scriptStat = spawnSync("node", ["--check", SCRIPT_PATH], {
			encoding: "utf-8",
		});
		assert.equal(
			scriptStat.status,
			0,
			"ci_monitor.cjs has valid JavaScript syntax",
		);
	});

	it("--help shows all commands", () => {
		const help = runScript(["--help"]);
		assert.equal(help.status, 0, "--help exits with code 0");
		assert.ok(help.stdout.includes("runs"), "help shows runs command");
		assert.ok(help.stdout.includes("watch"), "help shows watch command");
		assert.ok(
			help.stdout.includes("fail-fast"),
			"help shows fail-fast command",
		);
		assert.ok(
			help.stdout.includes("log-failed"),
			"help shows log-failed command",
		);
		assert.ok(
			help.stdout.includes("test-summary"),
			"help shows test-summary command",
		);
		assert.ok(
			help.stdout.includes("check-actions"),
			"help shows check-actions command",
		);
		assert.ok(help.stdout.includes("grep"), "help shows grep command");
		assert.ok(help.stdout.includes("wait-for"), "help shows wait-for command");
	});

	it("list-workflows finds workflow files or reports none", () => {
		const workflows = runScript(["list-workflows"]);
		if (workflows.status === 0) {
			assert.ok(
				workflows.stdout.includes(".yml") ||
					workflows.stdout.includes("No workflow files") ||
					workflows.stdout.includes("No .github"),
				"list-workflows output mentions yml files or none found",
			);
		} else {
			assert.ok(
				workflows.stderr.includes("No .github/workflows"),
				"list-workflows fails gracefully when no workflows dir",
			);
		}
	});

	it("check-actions validates workflow file", () => {
		const checkMissing = runScript([
			"check-actions",
			".github/workflows/nonexistent.yml",
		]);
		assert.notEqual(
			checkMissing.status,
			0,
			"check-actions fails for missing file",
		);
		assert.ok(
			checkMissing.stderr.includes("not found") ||
				checkMissing.stderr.includes("File not found"),
			"check-actions reports missing file",
		);
	});

	it("commands validate required arguments", () => {
		const grepNoPattern = runScript(["grep", "12345"]);
		assert.notEqual(grepNoPattern.status, 0, "grep fails without --pattern");
		assert.ok(
			grepNoPattern.stderr.includes("--pattern") ||
				grepNoPattern.stderr.includes("required"),
			"grep reports missing pattern",
		);

		const waitNoKeyword = runScript(["wait-for", "12345", "build"]);
		assert.notEqual(
			waitNoKeyword.status,
			0,
			"wait-for fails without --keyword",
		);
		assert.ok(
			waitNoKeyword.stderr.includes("--keyword") ||
				waitNoKeyword.stderr.includes("required"),
			"wait-for reports missing keyword",
		);

		const compareMissing = runScript(["compare", "12345"]);
		assert.notEqual(
			compareMissing.status,
			0,
			"compare fails with only one run-id",
		);
	});
});
