/**
 * Turn Status Parser (Tier 2.5 Phase 2)
 *
 * Purpose: extract turn_status markers from agent output to detect semantic state.
 * Allows agents to signal blocked/giving_up without requiring timeout or error detection.
 *
 * Consumer: auto.js, dispatch loop, or harness entry point where agent output is processed.
 */

import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";

/**
 * Extract turn_status marker from end of agent output.
 * Looks for `<turn_status>complete|blocked|giving_up</turn_status>` at end of response.
 *
 * @param {string} output - Full agent output text
 * @returns {object} - { status: "complete"|"blocked"|"giving_up"|null, cleanOutput: string }
 *
 * Purpose: harness can detect semantic state without waiting for timeout or errors.
 * Consumer: dispatch loop after agent response collected.
 */
export function extractTurnStatus(output) {
	if (!output || typeof output !== "string") {
		return { status: null, cleanOutput: output };
	}

	// Look for marker at end of output (allow trailing whitespace only).
	const markerRegex =
		/<turn_status>(complete|blocked|giving_up)<\/turn_status>\s*$/i;

	const match = output.match(markerRegex);

	if (!match) {
		return { status: null, cleanOutput: output };
	}

	const status = match[1].toLowerCase();

	// Remove marker from output for display
	const cleanOutput = output.replace(markerRegex, "").trimEnd();

	return {
		status,
		cleanOutput,
		markerFound: true,
	};
}

/**
 * Validate turn_status value.
 * Returns true if value is one of the three allowed states.
 *
 * @param {string} status - Status to validate
 * @returns {boolean}
 */
export function isValidTurnStatus(status) {
	return ["complete", "blocked", "giving_up"].includes(
		String(status).toLowerCase(),
	);
}

/**
 * Describe turn_status semantics for logging/debugging.
 *
 * @param {string} status - Status value
 * @returns {string} - Human-readable description
 */
export function describeTurnStatus(status) {
	switch (String(status).toLowerCase()) {
		case "complete":
			return "Task complete—agent verified and finished";

		case "blocked":
			return "Task blocked—discovered prerequisite or upstream failure";

		case "giving_up":
			return "Agent giving up—tried multiple approaches without success";

		default:
			return "Unknown status";
	}
}

/**
 * Parse turn_status and determine if unit should transition or pause.
 * Implements Tier 2.5 signal logic for dispatch harness.
 *
 * @param {string} turnStatus - Status from extractTurnStatus()
 * @returns {object} - { action: "continue"|"pause"|"reassess", signal?: string }
 *
 * Action meanings:
 * - "continue": normal completion path (status=complete)
 * - "pause": pause unit and wait for user (status=blocked → SignalPause)
 * - "reassess": transition to phase reassessment (status=giving_up → PhaseReassess)
 */
export function resolveSignalFromStatus(turnStatus) {
	switch (String(turnStatus).toLowerCase()) {
		case "complete":
			return {
				action: "continue",
				reason: "Agent marked task complete",
			};

		case "blocked":
			return {
				action: "pause",
				signal: "SignalPause",
				reason: "Agent discovered blocker—pausing for user",
			};

		case "giving_up":
			return {
				action: "reassess",
				signal: "PhaseReassess",
				reason: "Agent giving up—reassessing phase strategy",
			};

		default:
			return {
				action: "continue",
				reason: "No turn_status marker detected—using default completion path",
			};
	}
}

/**
 * End-to-end parse: extract status from output and resolve action.
 * Convenience wrapper combining extractTurnStatus() and resolveSignalFromStatus().
 *
 * @param {string} output - Full agent output
 * @returns {object} - { status, action, signal, cleanOutput, markerFound }
 */
export function parseTurnStatusFull(output) {
	const extracted = extractTurnStatus(output);
	const resolved = extracted.status
		? resolveSignalFromStatus(extracted.status)
		: { action: "continue", reason: "No marker found" };

	return {
		...extracted,
		...resolved,
	};
}

/**
 * Create a doctor check for turn_status usage in prompts.
 * Validates that all executable prompts have the marker template.
 *
 * @param {string} sfRoot - SF root directory
 * @returns {object} - { issues: [], allGood: boolean }
 */
export function checkTurnStatusPrompts(sfRoot) {
	const promptsDir = join(sfRoot, "src/resources/extensions/sf/prompts");
	const issues = [];

	if (!existsSync(promptsDir)) {
		return { issues: ["prompts directory not found"], allGood: false };
	}

	const executivePrompts = [
		"execute-task.md",
		"complete-slice.md",
		"research-slice.md",
		"plan-slice.md",
		"research-milestone.md",
		"plan-milestone.md",
	];

	for (const prompt of executivePrompts) {
		const promptPath = join(promptsDir, prompt);

		if (!existsSync(promptPath)) {
			issues.push(`Missing prompt: ${prompt}`);
			continue;
		}

		const content = readFileSync(promptPath, "utf8");

		if (!content.includes("<turn_status>")) {
			issues.push(`Prompt ${prompt} missing turn_status marker template`);
		}
	}

	return {
		issues,
		allGood: issues.length === 0,
		promptsChecked: executivePrompts.length,
	};
}
