import { createModuleRequire } from "../../utils/module-require.js";
import { getShellConfig, getShellEnv } from "../../utils/shell.js";
const NATIVE_PACKAGE = "@bastani/atomic-natives";
let cachedLoadResult;
export function resetNativePtyBindingCache() {
    cachedLoadResult = undefined;
}
function loadNativePtyBinding() {
    if (cachedLoadResult)
        return cachedLoadResult;
    try {
        const loaded = createModuleRequire(import.meta.url)(NATIVE_PACKAGE);
        if (typeof loaded.PtySession !== "function") {
            cachedLoadResult = { ok: false, error: new Error(`Native package ${NATIVE_PACKAGE} is missing PtySession.`) };
            return cachedLoadResult;
        }
        cachedLoadResult = { ok: true, binding: loaded };
        return cachedLoadResult;
    }
    catch (error) {
        cachedLoadResult = {
            ok: false,
            error: new Error(`Native PTY package ${NATIVE_PACKAGE} is unavailable for ${process.platform}-${process.arch}: ${error instanceof Error ? error.message : String(error)}`),
        };
        return cachedLoadResult;
    }
}
export async function executeNativePty(command, cwd, options) {
    const loaded = loadNativePtyBinding();
    if (!loaded.ok)
        throw loaded.error;
    if (options.signal?.aborted)
        throw new Error("aborted");
    const shellConfig = getShellConfig(options.shellPath);
    const session = new loaded.binding.PtySession();
    const onAbort = () => {
        try {
            session.kill();
        }
        catch { }
    };
    if (options.signal)
        options.signal.addEventListener("abort", onAbort, { once: true });
    try {
        const result = await session.start({
            command,
            cwd,
            env: { ...getShellEnv(), ...(options.env ?? {}), TERM: "xterm-256color" },
            timeoutMs: options.timeout !== undefined ? Math.max(1, Math.floor(options.timeout * 1000)) : undefined,
            cols: options.cols ?? 120,
            rows: options.rows ?? 40,
            shell: shellConfig.shell,
            shellArgs: shellConfig.args,
            commandTransport: shellConfig.commandTransport,
            closeStdinAfterCommand: shellConfig.commandTransport === "stdin",
        }, (_error, chunk) => {
            if (chunk)
                options.onData(Buffer.from(chunk));
        });
        if (options.signal?.aborted || result.cancelled)
            throw new Error("aborted");
        if (result.timedOut ?? result.timed_out)
            throw new Error(`timeout:${options.timeout}`);
        return { exitCode: result.exitCode ?? result.exit_code ?? null };
    }
    finally {
        if (options.signal)
            options.signal.removeEventListener("abort", onAbort);
    }
}
//# sourceMappingURL=bash-pty-native.js.map