import * as pty from "node-pty";
const MAX_HISTORY_BYTES = 1024 * 1024;
function normalizeOutputChunk(data) {
    if (typeof data === "string") {
        return Buffer.from(data, "utf8");
    }
    return Buffer.isBuffer(data) ? data : Buffer.from(data);
}
function terminatePtyProcess(ptyProcess) {
    const pid = ptyProcess.pid;
    ptyProcess.kill();
    if (process.platform !== "win32" && Number.isFinite(pid) && pid > 0) {
        try {
            process.kill(-pid, "SIGTERM");
        }
        catch {
            // Best effort: process group may already be gone or inaccessible.
        }
    }
}
export class PtySession {
    onDataCallback;
    onExitCallback;
    ptyProcess;
    outputHistory = [];
    historyBytes = 0;
    interrupted = false;
    constructor(ptyProcess, onDataCallback, onExitCallback) {
        this.onDataCallback = onDataCallback;
        this.onExitCallback = onExitCallback;
        this.ptyProcess = ptyProcess;
        this.ptyProcess.onData((data) => {
            const chunk = normalizeOutputChunk(data);
            this.outputHistory.push(chunk);
            this.historyBytes += chunk.byteLength;
            while (this.historyBytes > MAX_HISTORY_BYTES && this.outputHistory.length > 0) {
                const shifted = this.outputHistory.shift();
                if (!shifted) {
                    break;
                }
                this.historyBytes -= shifted.byteLength;
            }
            this.onDataCallback?.(chunk);
        });
        this.ptyProcess.onExit((event) => {
            this.onExitCallback?.(event);
        });
    }
    static spawn({ binary, args = [], cwd, env, cols, rows, onData, onExit }) {
        const ptyProcess = pty.spawn(binary, args, {
            name: "xterm-256color",
            cwd,
            env,
            cols,
            rows,
            encoding: null,
        });
        return new PtySession(ptyProcess, onData, onExit);
    }
    get pid() {
        return this.ptyProcess.pid;
    }
    getOutputHistory() {
        return this.outputHistory;
    }
    write(data) {
        this.ptyProcess.write(typeof data === "string" ? data : data.toString("utf8"));
    }
    resize(cols, rows, pixelWidth, pixelHeight) {
        if (pixelWidth !== undefined && pixelHeight !== undefined) {
            this.ptyProcess.resize(cols, rows, {
                width: pixelWidth,
                height: pixelHeight,
            });
            return;
        }
        this.ptyProcess.resize(cols, rows);
    }
    pause() {
        this.ptyProcess.pause();
    }
    resume() {
        this.ptyProcess.resume();
    }
    stop(options) {
        if (options?.interrupted) {
            this.interrupted = true;
        }
        terminatePtyProcess(this.ptyProcess);
    }
    wasInterrupted() {
        return this.interrupted;
    }
}
//# sourceMappingURL=pty-session.js.map