/**
 * Tests for the auto vs autonomous mode split.
 *
 * Verifies that:
 * - `/sf auto M001` produces canAskUser: true
 * - `/sf autonomous M001` produces canAskUser: false
 * - `/sf autonomous full` produces fullAutonomy: true, canAskUser: false
 * - The system-prompt autonomous-mode policy block is included when
 *   canAskUser=false and omitted otherwise.
 */

import assert from "node:assert/strict";
import { describe, it } from 'vitest';

// ── parseMilestoneTarget is already tested elsewhere; we just need
//    the command-handler logic that sets canAskUser. ──────────────────────────

/** Mirrors the verb-detection logic from commands/handlers/auto.ts */
function detectVerbs(input: string): {
	isAutoVerb: boolean;
	isAutonomousVerb: boolean;
	canAskUser: boolean;
	fullAutonomy: boolean;
} {
	const trimmed: string = input;
	const isAutonomousVerb =
		trimmed === "autonomous" || trimmed.startsWith("autonomous ");
	const isAutoVerb = trimmed === "auto" || trimmed.startsWith("auto ");
	const canAskUser = isAutoVerb;
	const afterVerb = trimmed.replace(/^(?:auto|autonomous)\b/, "").trim();
	const fullAutonomy =
		/\bfull\b/.test(afterVerb) || afterVerb.includes("--full");
	return { isAutoVerb, isAutonomousVerb, canAskUser, fullAutonomy };
}

describe("auto vs autonomous verb detection", () => {
	it("/sf auto → isAutoVerb=true, isAutonomousVerb=false", () => {
		const r = detectVerbs("auto M001");
		assert.equal(r.isAutoVerb, true);
		assert.equal(r.isAutonomousVerb, false);
	});

	it("/sf autonomous → isAutoVerb=false, isAutonomousVerb=true", () => {
		const r = detectVerbs("autonomous M001");
		assert.equal(r.isAutoVerb, false);
		assert.equal(r.isAutonomousVerb, true);
	});

	it("/sf auto M001 → canAskUser=true", () => {
		const r = detectVerbs("auto M001");
		assert.equal(r.canAskUser, true);
	});

	it("/sf autonomous M001 → canAskUser=false", () => {
		const r = detectVerbs("autonomous M001");
		assert.equal(r.canAskUser, false);
	});

	it("/sf autonomous full → fullAutonomy=true, canAskUser=false", () => {
		const r = detectVerbs("autonomous full");
		assert.equal(r.fullAutonomy, true);
		assert.equal(r.canAskUser, false);
	});

	it("/sf auto full → fullAutonomy=true, canAskUser=true", () => {
		const r = detectVerbs("auto full");
		assert.equal(r.fullAutonomy, true);
		assert.equal(r.canAskUser, true);
	});
});

describe("AutoSession.canAskUser defaults", () => {
	it("defaults to true on a fresh session", async () => {
		const { AutoSession } = await import("../auto/session.js");
		const session = new AutoSession();
		assert.equal(session.canAskUser, true);
	});

	it("reset() restores canAskUser to true", async () => {
		const { AutoSession } = await import("../auto/session.js");
		const session = new AutoSession();
		session.canAskUser = false;
		session.reset();
		assert.equal(session.canAskUser, true);
	});
});

describe("autonomous policy block in system prompt", () => {
	/**
	 * The policy block is built inline in buildBeforeAgentStartResult.
	 * We test the conditional logic directly rather than calling the full
	 * function (which requires a live project root and extension API).
	 */
	function buildAutonomousPolicyBlock(
		isAutoActive: boolean,
		canAskUser: boolean,
	): string {
		return isAutoActive && !canAskUser
			? `\n\n[INTERACTION POLICY — autonomous]\nYou are running in autonomous mode. Do NOT call \`ask_user_questions\`.\nResolve ambiguities by:\n1. Reading the codebase (sift, code-intelligence, source files)\n2. Web lookup (WebSearch, WebFetch, Context7)\n3. Inspecting prior decisions (.sf/DECISIONS.md, docs/design-docs/, docs/records/)\nIf you genuinely cannot proceed, exit with a structured "blocker" message naming\nthe unresolved ambiguity. The user will review at milestone close.`
			: "";
	}

	it("includes the policy block when auto active and canAskUser=false", () => {
		const block = buildAutonomousPolicyBlock(true, false);
		assert.ok(block.includes("[INTERACTION POLICY — autonomous]"));
		assert.ok(block.includes("Do NOT call `ask_user_questions`"));
		assert.ok(block.includes("blocker"));
	});

	it("omits the policy block when canAskUser=true (auto mode)", () => {
		const block = buildAutonomousPolicyBlock(true, true);
		assert.equal(block, "");
	});

	it("omits the policy block when auto is not active", () => {
		const block = buildAutonomousPolicyBlock(false, false);
		assert.equal(block, "");
	});
});
