"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runSubprocess = runSubprocess;
exports.checkSubprocess = checkSubprocess;
exports.runSubprocessCapture = runSubprocessCapture;
exports.runSubprocessCaptureSync = runSubprocessCaptureSync;
exports.checkSubprocessSync = checkSubprocessSync;
const platform_1 = require("./platform");
const child_process_1 = require("child_process");
/**
 * When shell mode is enabled, merge args into the command string so that
 * Node.js does not receive both a non-empty args array and `shell: true`.
 * Passing both triggers DEP0190 on Node ≥ 22 (and a warning on earlier
 * versions) because the arguments are concatenated without escaping.
 */
function resolveCommand(command, args, useShell) {
    if (useShell) {
        return { cmd: [command, ...args].join(' '), cmdArgs: [] };
    }
    return { cmd: command, cmdArgs: args };
}
async function runSubprocess(command, args, options = {}) {
    const shell = options.shell ?? platform_1.isWindows;
    const { cmd, cmdArgs } = resolveCommand(command, args, shell);
    return new Promise((resolve, reject) => {
        const child = (0, child_process_1.spawn)(cmd, cmdArgs, {
            cwd: options.cwd,
            env: options.env,
            stdio: options.stdio ?? 'inherit',
            shell,
        });
        child.on('error', reject);
        child.on('close', (code, signal) => {
            if (code === 0) {
                resolve();
                return;
            }
            const reason = code !== null ? `code ${code}` : `signal ${String(signal)}`;
            reject(new Error(`${command} exited with ${reason}`));
        });
    });
}
async function checkSubprocess(command, args, options = {}) {
    const shell = options.shell ?? platform_1.isWindows;
    const { cmd, cmdArgs } = resolveCommand(command, args, shell);
    return new Promise(resolve => {
        const child = (0, child_process_1.spawn)(cmd, cmdArgs, {
            cwd: options.cwd,
            env: options.env,
            stdio: options.stdio ?? 'ignore',
            shell,
        });
        child.on('error', () => resolve(false));
        child.on('close', code => resolve(code === 0));
    });
}
async function runSubprocessCapture(command, args, options = {}) {
    const shell = options.shell ?? platform_1.isWindows;
    const { cmd, cmdArgs } = resolveCommand(command, args, shell);
    return new Promise(resolve => {
        const child = (0, child_process_1.spawn)(cmd, cmdArgs, {
            cwd: options.cwd,
            env: options.env,
            stdio: 'pipe',
            shell,
        });
        let stdout = '';
        let stderr = '';
        child.stdout?.on('data', (chunk) => {
            stdout += typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString();
        });
        child.stderr?.on('data', (chunk) => {
            stderr += typeof chunk === 'string' ? chunk : Buffer.from(chunk).toString();
        });
        child.on('close', (code, signal) => {
            resolve({ stdout, stderr, code, signal });
        });
        child.on('error', () => {
            resolve({ stdout, stderr, code: -1, signal: null });
        });
    });
}
function runSubprocessCaptureSync(command, args, options = {}) {
    const shell = options.shell ?? platform_1.isWindows;
    const { cmd, cmdArgs } = resolveCommand(command, args, shell);
    const result = (0, child_process_1.spawnSync)(cmd, cmdArgs, {
        cwd: options.cwd,
        env: options.env,
        stdio: 'pipe',
        shell,
        encoding: 'utf-8',
    });
    return {
        stdout: result.stdout ?? '',
        stderr: result.stderr ?? '',
        code: result.status,
        signal: result.signal,
    };
}
function checkSubprocessSync(command, args, options = {}) {
    const shell = options.shell ?? platform_1.isWindows;
    const { cmd, cmdArgs } = resolveCommand(command, args, shell);
    try {
        const result = (0, child_process_1.spawnSync)(cmd, cmdArgs, {
            cwd: options.cwd,
            env: options.env,
            stdio: options.stdio ?? 'ignore',
            shell,
        });
        return result.status === 0;
    }
    catch {
        return false;
    }
}
//# sourceMappingURL=subprocess.js.map