import assert from "node:assert/strict";
import { execFileSync } from "node:child_process";
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from 'vitest';

import type { RunawayGuardPauseMetadata } from "../auto-runaway-guard.ts";
import { writeRunawayRecoveryArtifact } from "../runaway-recovery.ts";

function metadata(): RunawayGuardPauseMetadata {
	return {
		reason:
			"Runaway guard paused execute-task M004/S01/T04: budget kept growing after 2 diagnostic turn(s).",
		pausedAt: 1714447889000,
		unitType: "execute-task",
		unitId: "M004/S01/T04",
		diagnosticTurns: 2,
		warningsSent: 2,
		thresholdReasons: ["36 tool calls (warning 25)"],
		metrics: {
			toolCalls: 36,
			sessionTokens: 1_680_000,
			elapsedMs: 311_000,
			changedFiles: 2,
			topTools: { read: 12, edit: 4 },
		},
		lastWarningMetrics: {
			toolCalls: 25,
			sessionTokens: 1_000_000,
			elapsedMs: 240_000,
		},
		thresholds: {
			toolCallWarning: 25,
			tokenWarning: 1_000_000,
			elapsedMs: 1_200_000,
			changedFilesWarning: 75,
			minIntervalMs: 120_000,
		},
	};
}

test("writeRunawayRecoveryArtifact creates durable json and markdown handoff", () => {
	const dir = mkdtempSync(join(tmpdir(), "sf-runaway-recovery-"));
	try {
		execFileSync("git", ["init"], {
			cwd: dir,
			stdio: ["ignore", "ignore", "ignore"],
		});
		writeFileSync(join(dir, "changed.go"), "package main\n");

		const artifact = writeRunawayRecoveryArtifact(
			dir,
			metadata(),
			new Date("2026-04-30T06:00:00.000Z"),
		);

		assert.ok(artifact);
		assert.equal(artifact.kind, "runaway-recovery");
		assert.equal(artifact.unitId, "M004/S01/T04");
		assert.deepEqual(artifact.changedFiles, ["changed.go"]);
		assert.match(artifact.resumePrompt, /Do not broaden scope/);
		assert.match(artifact.recommendedAction, /verification-first/);
		assert.ok(existsSync(join(dir, artifact.jsonPath)));
		assert.ok(existsSync(join(dir, artifact.markdownPath)));

		const raw = JSON.parse(readFileSync(join(dir, artifact.jsonPath), "utf-8"));
		assert.equal(raw.version, 1);
		assert.equal(raw.metrics.toolCalls, 36);

		const markdown = readFileSync(join(dir, artifact.markdownPath), "utf-8");
		assert.match(markdown, /Runaway Recovery Handoff/);
		assert.match(markdown, /changed.go/);
		assert.match(markdown, /Resume Prompt/);
	} finally {
		rmSync(dir, { recursive: true, force: true });
	}
});
