import { TRPCError } from "@trpc/server";
import { parseCommandRunRequest, parseRuntimeConfigSaveRequest, parseShellSessionStartRequest, parseTaskSessionInputRequest, parseTaskSessionStartRequest, parseTaskSessionStopRequest, } from "../core/api-validation.js";
import { updateRuntimeConfig } from "../config/runtime-config.js";
import { buildRuntimeConfigResponse, resolveAgentCommand } from "../terminal/agent-registry.js";
import { discoverRuntimeSlashCommands } from "../terminal/slash-commands.js";
import { resolveTaskCwd } from "../workspace/task-worktree.js";
function normalizeOptionalTaskWorkspaceScopeInput(input) {
    if (!input) {
        return null;
    }
    const taskId = input.taskId.trim();
    const baseRef = input.baseRef.trim();
    if (!taskId || !baseRef) {
        throw new Error("baseRef query parameter requires taskId.");
    }
    return {
        taskId,
        baseRef,
    };
}
export function createRuntimeApi(deps) {
    return {
        loadConfig: async (workspaceScope) => {
            const scopedRuntimeConfig = await deps.loadScopedRuntimeConfig(workspaceScope);
            return buildRuntimeConfigResponse(scopedRuntimeConfig);
        },
        saveConfig: async (workspaceScope, input) => {
            const parsed = parseRuntimeConfigSaveRequest(input);
            const nextRuntimeConfig = await updateRuntimeConfig(workspaceScope.workspacePath, parsed);
            if (workspaceScope.workspaceId === deps.getActiveWorkspaceId()) {
                deps.setActiveRuntimeConfig(nextRuntimeConfig);
            }
            return buildRuntimeConfigResponse(nextRuntimeConfig);
        },
        loadSlashCommands: async (workspaceScope, input) => {
            try {
                const scopedRuntimeConfig = await deps.loadScopedRuntimeConfig(workspaceScope);
                const resolved = resolveAgentCommand(scopedRuntimeConfig);
                if (!resolved) {
                    return {
                        agentId: null,
                        commands: [],
                        error: "No runnable agent command is configured.",
                    };
                }
                const taskScope = normalizeOptionalTaskWorkspaceScopeInput(input);
                let commandCwd = workspaceScope.workspacePath;
                if (taskScope) {
                    commandCwd = await resolveTaskCwd({
                        cwd: workspaceScope.workspacePath,
                        taskId: taskScope.taskId,
                        baseRef: taskScope.baseRef,
                        ensure: false,
                    });
                }
                const discovered = await discoverRuntimeSlashCommands(resolved, commandCwd);
                return {
                    agentId: resolved.agentId,
                    commands: discovered.commands,
                    error: discovered.error,
                };
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                throw new TRPCError({
                    code: "INTERNAL_SERVER_ERROR",
                    message,
                });
            }
        },
        startTaskSession: async (workspaceScope, input) => {
            try {
                const body = parseTaskSessionStartRequest(input);
                const scopedRuntimeConfig = await deps.loadScopedRuntimeConfig(workspaceScope);
                const resolved = resolveAgentCommand(scopedRuntimeConfig);
                if (!resolved) {
                    return {
                        ok: false,
                        summary: null,
                        error: "No runnable agent command is configured. Open Settings, install a supported CLI, and select it.",
                    };
                }
                const taskCwd = await resolveTaskCwd({
                    cwd: workspaceScope.workspacePath,
                    taskId: body.taskId,
                    baseRef: body.baseRef,
                    ensure: true,
                });
                const terminalManager = await deps.getScopedTerminalManager(workspaceScope);
                const summary = await terminalManager.startTaskSession({
                    taskId: body.taskId,
                    agentId: resolved.agentId,
                    binary: resolved.binary,
                    args: resolved.args,
                    autonomousModeEnabled: scopedRuntimeConfig.agentAutonomousModeEnabled,
                    cwd: taskCwd,
                    prompt: body.prompt,
                    startInPlanMode: body.startInPlanMode,
                    resumeFromTrash: body.resumeFromTrash,
                    cols: body.cols,
                    rows: body.rows,
                    workspaceId: workspaceScope.workspaceId,
                });
                return {
                    ok: true,
                    summary,
                };
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                return {
                    ok: false,
                    summary: null,
                    error: message,
                };
            }
        },
        stopTaskSession: async (workspaceScope, input) => {
            try {
                const body = parseTaskSessionStopRequest(input);
                const terminalManager = await deps.getScopedTerminalManager(workspaceScope);
                const summary = terminalManager.stopTaskSession(body.taskId);
                return {
                    ok: Boolean(summary),
                    summary,
                };
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                return {
                    ok: false,
                    summary: null,
                    error: message,
                };
            }
        },
        sendTaskSessionInput: async (workspaceScope, input) => {
            try {
                const body = parseTaskSessionInputRequest(input);
                const terminalManager = await deps.getScopedTerminalManager(workspaceScope);
                const payloadText = body.appendNewline ? `${body.text}\n` : body.text;
                const summary = terminalManager.writeInput(body.taskId, Buffer.from(payloadText, "utf8"));
                if (!summary) {
                    return {
                        ok: false,
                        summary: null,
                        error: "Task session is not running.",
                    };
                }
                return {
                    ok: true,
                    summary,
                };
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                return {
                    ok: false,
                    summary: null,
                    error: message,
                };
            }
        },
        startShellSession: async (workspaceScope, input) => {
            try {
                const body = parseShellSessionStartRequest(input);
                const terminalManager = await deps.getScopedTerminalManager(workspaceScope);
                const shell = deps.resolveInteractiveShellCommand();
                const shellCwd = body.workspaceTaskId
                    ? await resolveTaskCwd({
                        cwd: workspaceScope.workspacePath,
                        taskId: body.workspaceTaskId,
                        baseRef: body.baseRef,
                        ensure: true,
                    })
                    : workspaceScope.workspacePath;
                const summary = await terminalManager.startShellSession({
                    taskId: body.taskId,
                    cwd: shellCwd,
                    cols: body.cols,
                    rows: body.rows,
                    binary: shell.binary,
                    args: shell.args,
                });
                return {
                    ok: true,
                    summary,
                    shellBinary: shell.binary,
                };
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                return {
                    ok: false,
                    summary: null,
                    shellBinary: null,
                    error: message,
                };
            }
        },
        runCommand: async (workspaceScope, input) => {
            try {
                const body = parseCommandRunRequest(input);
                return await deps.runCommand(body.command, workspaceScope.workspacePath);
            }
            catch (error) {
                const message = error instanceof Error ? error.message : String(error);
                throw new TRPCError({
                    code: "INTERNAL_SERVER_ERROR",
                    message,
                });
            }
        },
    };
}
//# sourceMappingURL=runtime-api.js.map