import { spawnSync } from "node:child_process";
import { RUNTIME_AGENT_CATALOG } from "../core/agent-catalog.js";
function getDefaultArgs(agentId) {
    const entry = RUNTIME_AGENT_CATALOG.find((candidate) => candidate.id === agentId);
    if (!entry) {
        return [];
    }
    return [...entry.baseArgs];
}
function isBinaryAvailableOnPath(binary) {
    const trimmed = binary.trim();
    if (!trimmed) {
        return false;
    }
    if (trimmed.includes("/") || trimmed.includes("\\")) {
        // Path-based commands are validated at spawn-time.
        return true;
    }
    const lookupCommand = process.platform === "win32" ? "where" : "which";
    const result = spawnSync(lookupCommand, [trimmed], {
        stdio: "ignore",
    });
    return result.status === 0;
}
function getShellBinary() {
    if (process.platform === "win32") {
        return process.env.ComSpec?.trim() || "cmd.exe";
    }
    const shell = process.env.SHELL?.trim();
    return shell || "/bin/bash";
}
function quotePosixWord(value) {
    return `'${value.replaceAll("'", "'\\''")}'`;
}
function isBinaryResolvableInShell(binary) {
    const trimmed = binary.trim();
    if (!trimmed) {
        return false;
    }
    const shellBinary = getShellBinary();
    if (!shellBinary) {
        return false;
    }
    if (process.platform === "win32") {
        const result = spawnSync(shellBinary, ["/d", "/s", "/c", `where ${trimmed} >NUL 2>NUL`], {
            stdio: "ignore",
        });
        return result.status === 0;
    }
    const result = spawnSync(shellBinary, ["-ic", `command -v ${quotePosixWord(trimmed)} >/dev/null 2>&1`], {
        stdio: "ignore",
    });
    return result.status === 0;
}
function toShellLaunchCommand(commandLine) {
    const trimmed = commandLine.trim();
    if (!trimmed) {
        return null;
    }
    const shellBinary = getShellBinary();
    if (!shellBinary) {
        return null;
    }
    if (process.platform === "win32") {
        return {
            binary: shellBinary,
            args: ["/d", "/s", "/c", trimmed],
        };
    }
    return {
        binary: shellBinary,
        args: ["-ic", trimmed],
    };
}
function quoteForDisplay(part) {
    if (/^[A-Za-z0-9_./:@%+=,-]+$/.test(part)) {
        return part;
    }
    return JSON.stringify(part);
}
function joinCommand(binary, args) {
    if (args.length === 0) {
        return binary;
    }
    return [binary, ...args.map(quoteForDisplay)].join(" ");
}
export function detectInstalledCommands() {
    const candidates = [...RUNTIME_AGENT_CATALOG.map((entry) => entry.binary), "npx"];
    const detected = [];
    for (const candidate of candidates) {
        if (isBinaryAvailableOnPath(candidate) || isBinaryResolvableInShell(candidate)) {
            detected.push(candidate);
        }
    }
    return detected;
}
function getCuratedDefinitions(runtimeConfig, detected) {
    const detectedSet = new Set(detected);
    return RUNTIME_AGENT_CATALOG.map((entry) => {
        const defaultArgs = getDefaultArgs(entry.id);
        const command = joinCommand(entry.binary, defaultArgs);
        return {
            id: entry.id,
            label: entry.label,
            binary: entry.binary,
            command,
            defaultArgs,
            installed: detectedSet.has(entry.binary),
            configured: runtimeConfig.selectedAgentId === entry.id,
        };
    });
}
export function resolveAgentCommand(runtimeConfig) {
    const selected = RUNTIME_AGENT_CATALOG.find((entry) => entry.id === runtimeConfig.selectedAgentId);
    if (!selected) {
        return null;
    }
    const defaultArgs = getDefaultArgs(selected.id);
    const command = joinCommand(selected.binary, defaultArgs);
    if (isBinaryAvailableOnPath(selected.binary)) {
        return {
            agentId: selected.id,
            label: selected.label,
            command,
            binary: selected.binary,
            args: defaultArgs,
        };
    }
    if (isBinaryResolvableInShell(selected.binary)) {
        const shellLaunch = toShellLaunchCommand(command);
        if (!shellLaunch) {
            return null;
        }
        return {
            agentId: selected.id,
            label: selected.label,
            command,
            binary: shellLaunch.binary,
            args: shellLaunch.args,
        };
    }
    return null;
}
export function buildRuntimeConfigResponse(runtimeConfig) {
    const detectedCommands = detectInstalledCommands();
    const agents = getCuratedDefinitions(runtimeConfig, detectedCommands);
    const resolved = resolveAgentCommand(runtimeConfig);
    const effectiveCommand = resolved ? joinCommand(resolved.binary, resolved.args) : null;
    return {
        selectedAgentId: runtimeConfig.selectedAgentId,
        selectedShortcutLabel: runtimeConfig.selectedShortcutLabel,
        agentAutonomousModeEnabled: runtimeConfig.agentAutonomousModeEnabled,
        effectiveCommand,
        globalConfigPath: runtimeConfig.globalConfigPath,
        projectConfigPath: runtimeConfig.projectConfigPath,
        readyForReviewNotificationsEnabled: runtimeConfig.readyForReviewNotificationsEnabled,
        detectedCommands,
        agents,
        shortcuts: runtimeConfig.shortcuts,
        commitPromptTemplate: runtimeConfig.commitPromptTemplate,
        openPrPromptTemplate: runtimeConfig.openPrPromptTemplate,
        commitPromptTemplateDefault: runtimeConfig.commitPromptTemplateDefault,
        openPrPromptTemplateDefault: runtimeConfig.openPrPromptTemplateDefault,
    };
}
//# sourceMappingURL=agent-registry.js.map