import { spawnProcess, spawnProcessSync } from "../utils/child-process.js";
import { isStdoutTakenOver } from "./output-guard.js";
import { getCommandEnv } from "./package-manager-env.js";
function spawnCommand(command, args, options) {
    return spawnProcess(command, args, {
        cwd: options?.cwd,
        stdio: isStdoutTakenOver() ? ["ignore", 2, 2] : "inherit",
        env: getCommandEnv(command),
    });
}
function spawnCaptureCommand(command, args, options) {
    return spawnProcess(command, args, {
        cwd: options?.cwd,
        stdio: ["ignore", "pipe", "pipe"],
        env: getCommandEnv(command, options?.env),
    });
}
export function runCommandCapture(command, args, options) {
    return new Promise((resolvePromise, reject) => {
        const child = spawnCaptureCommand(command, args, options);
        let stdout = "";
        let stderr = "";
        let timedOut = false;
        const timeout = typeof options?.timeoutMs === "number"
            ? setTimeout(() => {
                timedOut = true;
                child.kill();
            }, options.timeoutMs)
            : undefined;
        child.stdout?.on("data", (data) => {
            stdout += data.toString();
        });
        child.stderr?.on("data", (data) => {
            stderr += data.toString();
        });
        child.once("error", (error) => {
            if (timeout)
                clearTimeout(timeout);
            reject(error);
        });
        child.once("close", (code, signal) => {
            if (timeout)
                clearTimeout(timeout);
            if (timedOut) {
                reject(new Error(`${command} ${args.join(" ")} timed out after ${options?.timeoutMs}ms`));
                return;
            }
            if (code === 0) {
                resolvePromise(stdout.trim());
                return;
            }
            const exitStatus = code === null ? `signal ${signal ?? "unknown"}` : `code ${code}`;
            reject(new Error(`${command} ${args.join(" ")} failed with ${exitStatus}: ${stderr || stdout}`));
        });
    });
}
export function runCommand(command, args, options) {
    return new Promise((resolvePromise, reject) => {
        const child = spawnCommand(command, args, options);
        child.on("error", reject);
        child.on("exit", (code) => {
            if (code === 0) {
                resolvePromise();
            }
            else {
                reject(new Error(`${command} ${args.join(" ")} failed with code ${code}`));
            }
        });
    });
}
export function runCommandSync(command, args) {
    const result = spawnProcessSync(command, args, {
        stdio: ["ignore", "pipe", "pipe"],
        encoding: "utf-8",
        env: getCommandEnv(command),
    });
    if (result.error || result.status !== 0) {
        throw new Error(`Failed to run ${command} ${args.join(" ")}: ${result.error?.message || result.stderr || result.stdout}`);
    }
    return (result.stdout || result.stderr || "").trim();
}
export async function runWithConcurrency(tasks, limit) {
    if (tasks.length === 0) {
        return [];
    }
    const results = new Array(tasks.length);
    let nextIndex = 0;
    const workerCount = Math.max(1, Math.min(limit, tasks.length));
    const worker = async () => {
        while (true) {
            const index = nextIndex;
            nextIndex += 1;
            if (index >= tasks.length) {
                return;
            }
            results[index] = await tasks[index]();
        }
    };
    await Promise.all(Array.from({ length: workerCount }, () => worker()));
    return results;
}
//# sourceMappingURL=package-manager-command.js.map