import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import { test } from "vitest";

const __dirname = dirname(fileURLToPath(import.meta.url));
const subagentSrc = readFileSync(
	join(__dirname, "../resources/extensions/sf/subagent/index.js"),
	"utf-8",
);

test("subagent schema declares debate mode and bounded rounds", () => {
	const paramsStart = subagentSrc.indexOf(
		"const SubagentParams = Type.Object({",
	);
	const paramsEnd = subagentSrc.indexOf("});", paramsStart);
	const paramsBlock = subagentSrc.slice(paramsStart, paramsEnd);

	assert.match(paramsBlock, /mode:\s*Type\.Optional\(TaskBatchModeSchema\)/);
	assert.match(paramsBlock, /rounds:\s*Type\.Optional\(\s*Type\.Integer/);
	assert.match(paramsBlock, /minimum:\s*1/);
	assert.match(paramsBlock, /maximum:\s*5/);
});

test("subagent debate mode injects prior-round transcript", () => {
	assert.match(
		subagentSrc,
		/params\.mode\s*===\s*"debate"/,
		"dispatch should branch on mode: debate",
	);
	assert.match(
		subagentSrc,
		/const\s+transcriptEntries\s*=\s*\[\]/,
		"debate should maintain a transcript across rounds",
	);
	assert.match(
		subagentSrc,
		/Debate transcript so far:/,
		"debate prompt should include the transcript",
	);
	assert.match(
		subagentSrc,
		/final round/i,
		"final debate round should ask for a final verdict",
	);
});

test("subagent details includes debate as a first-class mode", () => {
	assert.match(
		subagentSrc,
		/TaskBatchModeSchema\s*=\s*StringEnum\(\["parallel",\s*"debate"\]/,
	);
	assert.match(
		subagentSrc,
		/details\.mode\s*===\s*"parallel"\s*\|\|\s*details\.mode\s*===\s*"debate"/,
		"renderer should handle debate mode alongside parallel batches",
	);
});

test("subagent default execution uses in-process runner instead of recursive sf spawn", () => {
	const start = subagentSrc.indexOf("async function runSingleAgent(");
	const end = subagentSrc.indexOf(
		"async function runSingleAgentInCmuxSplit(",
		start,
	);
	assert.ok(start >= 0, "runSingleAgent should exist");
	assert.ok(end > start, "runSingleAgent block should be found");

	const runSingleAgentBlock = subagentSrc.slice(start, end);
	assert.match(runSingleAgentBlock, /await\s+runSubagent\(/);
	assert.doesNotMatch(runSingleAgentBlock, /spawn\(/);
	assert.doesNotMatch(runSingleAgentBlock, /buildSubagentProcessArgs\(/);
});
