"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveBinaryPath = resolveBinaryPath;
exports.ensureBinaryExists = ensureBinaryExists;
exports.launch = launch;
exports.run = run;
const node_fs_1 = __importDefault(require("node:fs"));
const node_path_1 = __importDefault(require("node:path"));
const node_child_process_1 = require("node:child_process");
const targets_1 = require("./targets");
function resolveBinaryPath(options = {}) {
    const rootDir = options.rootDir ?? node_path_1.default.resolve(__dirname, "..", "..", "..");
    const processLike = options.processLike ?? process;
    const target = (0, targets_1.resolveTarget)(processLike);
    return node_path_1.default.join(rootDir, (0, targets_1.vendorRelativePath)(target));
}
function ensureBinaryExists(binaryPath) {
    if (node_fs_1.default.existsSync(binaryPath)) {
        return;
    }
    const error = new Error(`No packaged skilly binary was found at ${binaryPath}. Reinstall ${targets_1.PACKAGE_NAME} or rebuild the npm package with staged native binaries.`);
    error.code = "ERR_MISSING_BINARY";
    throw error;
}
function launch(argv, options = {}) {
    const processLike = options.processLike ?? process;
    const spawnImpl = options.spawnImpl ?? node_child_process_1.spawn;
    const binaryPath = resolveBinaryPath(options);
    ensureBinaryExists(binaryPath);
    const child = spawnImpl(binaryPath, argv, {
        env: processLike.env,
        stdio: "inherit",
        windowsHide: false
    });
    return { child, binaryPath };
}
function writeError(processLike, message) {
    if (processLike.stderr && typeof processLike.stderr.write === "function") {
        processLike.stderr.write(`${message}\n`);
        return;
    }
    console.error(message);
}
function run(argv, options = {}) {
    const processLike = options.processLike ?? process;
    const { child, binaryPath } = launch(argv, options);
    child.once("error", (error) => {
        writeError(processLike, `Failed to launch skilly from ${binaryPath}: ${error.message}`);
        processLike.exit(1);
    });
    child.once("close", (code, signal) => {
        if (signal) {
            processLike.kill(processLike.pid, signal);
            return;
        }
        processLike.exit(code ?? 1);
    });
    return child;
}
