import assert from "node:assert/strict";
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, it } from "vitest";
import {
	evaluatePythonRuntimeGuard,
	invokesBarePython,
	readPythonRuntimeRequirement,
} from "./project-runtime-guard.js";

function makeProject(files: Record<string, string>): string {
	const dir = mkdtempSync(join(tmpdir(), "sf-project-runtime-"));
	for (const [relativePath, content] of Object.entries(files)) {
		const path = join(dir, relativePath);
		mkdirSync(join(path, ".."), { recursive: true });
		writeFileSync(path, content, "utf-8");
	}
	return dir;
}

describe("project runtime guard", () => {
	it("detects bare python commands with environment assignments", () => {
		assert.equal(
			invokesBarePython("TEST_DB_ALLOWED=1 python -m pytest tests"),
			true,
		);
		assert.equal(
			invokesBarePython("mise exec -- python -m pytest tests"),
			false,
		);
		assert.equal(invokesBarePython("uv run python -m pytest tests"), false);
	});

	it("uses project python declarations over host interpreter assumptions", () => {
		const dir = makeProject({
			"pyproject.toml": '[project]\nrequires-python = ">=3.14"\n',
			"mise.toml": '[tools]\npython = "3.14"\n',
		});

		const requirement = readPythonRuntimeRequirement(dir);
		assert.deepEqual(requirement, {
			version: "3.14",
			source: "pyproject.toml",
		});

		const result = evaluatePythonRuntimeGuard(
			"TEST_DB_ALLOWED=1 python -m pytest python/tests/integration",
			dir,
			{
				executable:
					"/home/example/.local/share/mise/installs/python/3.11/bin/python",
				version: "3.11.12",
			},
		);

		assert.equal(result?.blocked, true);
		assert.match(result?.message ?? "", /Project declares Python >=3\.14/);
		assert.match(result?.message ?? "", /Do not modify project code/);
	});

	it("allows bare python when the active interpreter satisfies the project", () => {
		const dir = makeProject({
			"pyproject.toml": '[project]\nrequires-python = ">=3.14"\n',
		});

		const result = evaluatePythonRuntimeGuard("python -m pytest", dir, {
			executable: "/opt/python/3.14/bin/python",
			version: "3.14.4",
		});

		assert.equal(result, null);
	});
});
