import { spawn } from "child_process";
export class BangManager {
    constructor(container, options) {
        this.container = container;
        this.isCommandRunning = false;
        this.currentProcess = null;
        this.workdir = options.workdir;
    }
    get messageManager() {
        return this.container.get("MessageManager");
    }
    setCommandRunning(isRunning) {
        this.isCommandRunning = isRunning;
    }
    async executeCommand(command) {
        if (this.isCommandRunning) {
            throw new Error("Command already running");
        }
        this.setCommandRunning(true);
        // Add bang placeholder
        this.messageManager.addBangMessage(command);
        return new Promise((resolve) => {
            const child = spawn(command, {
                shell: true,
                stdio: "pipe",
                cwd: this.workdir,
                env: {
                    ...process.env,
                },
            });
            this.currentProcess = child;
            let outputBuffer = "";
            const updateOutput = (newData) => {
                outputBuffer += newData;
            };
            child.stdout?.on("data", (data) => {
                updateOutput(data.toString());
            });
            child.stderr?.on("data", (data) => {
                updateOutput(data.toString());
            });
            child.on("exit", (code, signal) => {
                const exitCode = code === null && signal ? 130 : (code ?? 0);
                this.messageManager.completeBangMessage(command, exitCode, outputBuffer);
                this.setCommandRunning(false);
                this.currentProcess = null;
                resolve(exitCode);
            });
            child.on("error", (error) => {
                updateOutput(`\nError: ${error.message}\n`);
                this.messageManager.completeBangMessage(command, 1, outputBuffer);
                this.setCommandRunning(false);
                this.currentProcess = null;
                resolve(1);
            });
        });
    }
    abortCommand() {
        if (this.currentProcess && this.isCommandRunning) {
            this.currentProcess.kill("SIGKILL");
            this.currentProcess = null;
            this.isCommandRunning = false;
        }
    }
}
