#!/usr/bin/env node
/**
 * Reproduce the kernel-venv install race against a real uv install.
 *
 * A rebuild replaces ~/.prime/agent/kernel-venv while other sessions may be booting a
 * kernel from it. This probe runs the real bootstrap (staged temp venv, PRIME_AGENT_KERNEL_VENV
 * pointed at it) and a reader that keeps launching the venv's own python to import the
 * runtime, so it measures what a concurrently booting kernel would have imported.
 *
 * Usage: node scripts/kernel-venv-race-probe.mjs [--venv <dir>] [--samples <file>]
 * Exits non-zero when any sample caught the live path holding a partial venv.
 */
import { spawn, spawnSync } from "node:child_process";
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";

const repoRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
const BOOTSTRAP_CLI = join(repoRoot, "packages", "coding-agent", "src", "core", "kernel", "bootstrap-cli.ts");

function argValue(name, fallback) {
	const index = process.argv.indexOf(name);
	return index >= 0 ? process.argv[index + 1] : fallback;
}

const venv = resolve(argValue("--venv", mkdtempSync(join(tmpdir(), "prime-agent-venv-race-"))));
const samplesPath = argValue("--samples", `${venv}.samples.json`);
const python = join(venv, "bin", "python");
const manifest = join(venv, ".bootstrap-version");

function bootstrap() {
	return new Promise((settle) => {
		const child = spawn("npx", ["tsx", BOOTSTRAP_CLI], {
			cwd: repoRoot,
			stdio: ["ignore", "ignore", "inherit"],
			env: { ...process.env, PRIME_AGENT_KERNEL_VENV: venv },
		});
		child.on("close", (code) => settle(code));
	});
}

/** What a kernel booting right now would import, plus the state it would read. */
function inspect() {
	// Read the whole fs state first, so every field of one sample describes one instant.
	const venvExists = existsSync(venv);
	const pythonExists = venvExists && existsSync(python);
	const manifestExists = venvExists && existsSync(manifest);
	const attempt = pythonExists
		? spawnSync(python, ["-c", "import rlm, rlm.mcp, remote"], { encoding: "utf8", timeout: 30_000 })
		: undefined;
	const importOk = attempt?.status === 0;
	return {
		venvExists,
		pythonExists,
		manifestExists,
		importOk,
		error: importOk ? "" : ((attempt?.stderr ?? (pythonExists ? "" : "no python")).trim().split("\n").at(-1) ?? ""),
	};
}

function sample(index) {
	let entry = inspect();
	// The swap renames the live venv away and back within two renames; re-read once so a
	// transition between two complete trees is not mistaken for a partially installed one.
	if (entry.venvExists && !entry.importOk) entry = inspect();
	// Partial is the bug: the live path is there but cannot serve the runtime.
	return { index, ...entry, partial: entry.venvExists && (!entry.importOk || !entry.manifestExists) };
}

async function main() {
	// First build: the state every later boot starts from.
	if ((await bootstrap()) !== 0) {
		throw new Error("the first bootstrap failed; the probe needs a working uv and network");
	}
	console.log(`warm venv: ${python}`);

	const samples = [];
	let building = true;
	const reader = (async () => {
		for (let index = 0; building; index += 1) {
			samples.push(sample(index));
			await new Promise((settle) => setTimeout(settle, 50));
		}
		samples.push(sample(samples.length));
	})();

	// Second build: a rebuild of the same venv, the 2026-09-17 install path.
	const rebuildCode = await bootstrap();
	building = false;
	await reader;

	const partial = samples.filter((entry) => entry.partial);
	const absent = samples.filter((entry) => !entry.venvExists);
	const complete = samples.filter((entry) => entry.venvExists && entry.importOk);
	writeFileSync(samplesPath, `${JSON.stringify({ venv, rebuildCode, samples }, null, 2)}\n`);
	console.log(`samples: ${samples.length} complete=${complete.length} absent=${absent.length} partial=${partial.length}`);
	for (const entry of partial.slice(0, 5)) {
		console.log(`  partial sample ${entry.index}: manifest=${entry.manifestExists} ${entry.error}`);
	}
	console.log(`samples file: ${samplesPath}`);
	if (rebuildCode !== 0) throw new Error(`the rebuild failed with exit code ${rebuildCode}`);
	if (partial.length > 0) throw new Error("a concurrently booting kernel imported the venv mid-install");

	const manifestRuntime = JSON.parse(readFileSync(manifest, "utf8")).runtime;
	console.log(`promoted runtime: ${manifestRuntime}`);
	if (process.env.PRIME_AGENT_RACE_PROBE_KEEP !== "1") {
		rmSync(venv, { recursive: true, force: true });
	}
}

main().catch((error) => {
	console.error(error instanceof Error ? error.message : String(error));
	process.exitCode = 1;
});
