"use strict";
/**
 * Claude Spawner Utilities
 *
 * Cross-platform Claude CLI spawn utilities for CCS.
 * Handles Windows .cmd/.bat/.ps1 files properly.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.needsShellExecution = exports.execClaudeWithExitHandling = exports.spawnClaudeSync = exports.spawnClaude = void 0;
const child_process_1 = require("child_process");
const shell_executor_1 = require("./shell-executor");
const claude_detector_1 = require("./claude-detector");
const error_manager_1 = require("./error-manager");
/**
 * Spawn Claude CLI with cross-platform support.
 *
 * Handles Windows .cmd/.bat/.ps1 wrappers automatically.
 * Returns the ChildProcess for custom event handling.
 *
 * @throws Error if Claude CLI is not found
 */
function spawnClaude(options = {}) {
    const claudeInfo = (0, claude_detector_1.getClaudeCliInfo)();
    if (!claudeInfo) {
        throw new Error('Claude CLI not found');
    }
    const { path: claudeCli, needsShell } = claudeInfo;
    const { args = [], env, cwd, stdio = 'inherit' } = options;
    // Merge environment
    const mergedEnvBase = env ? { ...process.env, ...env } : process.env;
    const mergedEnv = (0, shell_executor_1.stripClaudeCodeEnv)(mergedEnvBase);
    let child;
    if (needsShell) {
        // Windows .cmd/.bat/.ps1: concatenate into string to avoid DEP0190 warning
        const cmdString = [claudeCli, ...args].map(shell_executor_1.escapeShellArg).join(' ');
        child = (0, child_process_1.spawn)(cmdString, {
            stdio,
            windowsHide: true,
            shell: (0, shell_executor_1.getWindowsEscapedCommandShell)(),
            env: mergedEnv,
            cwd,
        });
    }
    else {
        // Unix or Windows native: use array form (faster, no shell overhead)
        child = (0, child_process_1.spawn)(claudeCli, args, {
            stdio,
            windowsHide: true,
            env: mergedEnv,
            cwd,
        });
    }
    return { child, claudePath: claudeCli };
}
exports.spawnClaude = spawnClaude;
/**
 * Spawn Claude CLI and wait for exit.
 *
 * Convenience function that returns a promise resolving to the exit code.
 */
function spawnClaudeSync(options = {}) {
    return new Promise((resolve, reject) => {
        try {
            const { child } = spawnClaude(options);
            child.on('exit', (code) => {
                resolve(code ?? 0);
            });
            child.on('error', (error) => {
                reject(error);
            });
        }
        catch (error) {
            reject(error);
        }
    });
}
exports.spawnClaudeSync = spawnClaudeSync;
/**
 * Spawn Claude CLI with automatic exit handling.
 *
 * Exits the current process when Claude exits, preserving exit code/signal.
 * Used for simple pass-through scenarios.
 */
function execClaudeWithExitHandling(options = {}) {
    let result;
    try {
        result = spawnClaude(options);
    }
    catch {
        // Claude not found - show error and exit
        void error_manager_1.ErrorManager.showClaudeNotFound();
        process.exit(1);
    }
    const { child } = result;
    child.on('exit', (code, signal) => {
        if (signal) {
            process.kill(process.pid, signal);
        }
        else {
            process.exit(code ?? 0);
        }
    });
    child.on('error', async () => {
        await error_manager_1.ErrorManager.showClaudeNotFound();
        process.exit(1);
    });
}
exports.execClaudeWithExitHandling = execClaudeWithExitHandling;
/**
 * Check if shell execution is needed for a given path.
 *
 * Returns true for Windows .cmd/.bat/.ps1 files.
 */
function needsShellExecution(executablePath) {
    const isWindows = process.platform === 'win32';
    return isWindows && /\.(cmd|bat|ps1)$/i.test(executablePath);
}
exports.needsShellExecution = needsShellExecution;
//# sourceMappingURL=claude-spawner.js.map