"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.execWithProcessGroupKill = execWithProcessGroupKill;
const child_process_1 = require("child_process");
const DEFAULT_SIGKILL_GRACE_MS = 5000;
function execWithProcessGroupKill(command, options) {
    return new Promise((resolve) => {
        const shell = process.env.SHELL || '/bin/bash';
        const sigkillGraceMs = options.sigkillGraceMs ?? DEFAULT_SIGKILL_GRACE_MS;
        const childProcess = (0, child_process_1.spawn)(shell, ['-c', command], {
            cwd: options.cwd,
            detached: true,
            stdio: ['pipe', 'pipe', 'pipe'],
        });
        let killed = false;
        let resolved = false;
        let extraStderr = '';
        const stdoutChunks = [];
        const stderrChunks = [];
        childProcess.stdout?.on('data', (chunk) => {
            stdoutChunks.push(chunk);
        });
        childProcess.stderr?.on('data', (chunk) => {
            stderrChunks.push(chunk);
        });
        const doResolve = (exitCode) => {
            if (resolved)
                return;
            resolved = true;
            clearTimeout(timeoutTimer);
            clearTimeout(sigkillTimer);
            const stdout = Buffer.concat(stdoutChunks).toString('utf-8');
            const stderr = Buffer.concat(stderrChunks).toString('utf-8') + extraStderr;
            resolve({ stdout, stderr, killed, exitCode });
        };
        let sigkillTimer;
        const timeoutTimer = setTimeout(() => {
            killed = true;
            try {
                process.kill(-childProcess.pid, 'SIGTERM');
            }
            catch {
            }
            sigkillTimer = setTimeout(() => {
                try {
                    process.kill(-childProcess.pid, 'SIGKILL');
                }
                catch {
                }
            }, sigkillGraceMs);
        }, options.timeout);
        childProcess.on('close', (code) => {
            doResolve(code);
        });
        childProcess.on('error', (err) => {
            extraStderr += `\nSpawn error: ${err.message}`;
        });
    });
}
//# sourceMappingURL=spawn-with-kill.js.map