/**
 * Download pre-built mk3-tui into a user cache when the npm package has no binary.
 * Maintainers: attach release assets to GitHub, e.g. for v2.9.106 tag upload
 *   mk3-tui-win32-x64.exe, mk3-tui-linux-x64, mk3-tui-darwin-arm64, mk3-tui-darwin-x64
 * Or attach the same names to the "latest" release for a rolling fallback.
 *
 * Opt out: NO_MK3_DOWNLOAD=1
 * Override: MK3_TUI_DOWNLOAD_URL=https://.../mk3-tui-win32-x64.exe
 */
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
const DOWNLOAD_TIMEOUT_MS = 120_000;
const MIN_BYTES = 20_000;
export function getMk3UserCacheDir() {
    if (process.platform === 'win32') {
        const base = process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
        return path.join(base, '4runr-os', 'bin');
    }
    const xdg = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');
    return path.join(xdg, '4runr-os', 'bin');
}
export function getMk3UserCachePath(binaryName) {
    return path.join(getMk3UserCacheDir(), binaryName);
}
function getVersionedMk3UserCachePath(binaryName, version) {
    const safeVersion = version.replace(/[^a-zA-Z0-9._-]/g, '_');
    return path.join(getMk3UserCacheDir(), safeVersion, binaryName);
}
function parseGithubRepo(pkg) {
    const raw = pkg.repository;
    let url = typeof raw === 'string' ? raw : raw?.url;
    if (!url)
        return null;
    url = url.replace(/^git\+/, '').replace(/\.git$/i, '');
    const m = url.match(/github\.com[/:]([^/]+)\/([^/]+?)(?:\.git)?$/i);
    if (!m)
        return null;
    return { owner: m[1], repo: m[2] };
}
function releaseAssetNames(binaryName) {
    const platform = process.platform;
    const arch = process.arch;
    const key = `${platform}-${arch}`;
    const ordered = [];
    if (platform === 'win32') {
        ordered.push(`mk3-tui-${key}.exe`, binaryName, 'mk3-tui.exe');
    }
    else {
        ordered.push(`mk3-tui-${key}`, binaryName, 'mk3-tui');
    }
    return [...new Set(ordered)];
}
function looksLikeExecutable(buf) {
    if (buf.length < 4)
        return false;
    if (buf[0] === 0x4d && buf[1] === 0x5a)
        return true;
    if (buf[0] === 0x7f && buf[1] === 0x45 && buf[2] === 0x4c && buf[3] === 0x46)
        return true;
    const be = buf.readUInt32BE(0);
    const le = buf.readUInt32LE(0);
    if (be === 0xcafebabe ||
        be === 0xcefaedfe ||
        be === 0xcffaedfe ||
        le === 0xfeedface ||
        le === 0xfeedfacf) {
        return true;
    }
    return false;
}
async function fetchUrlToBuffer(url) {
    const ctrl = new AbortController();
    const timer = setTimeout(() => ctrl.abort(), DOWNLOAD_TIMEOUT_MS);
    try {
        const res = await fetch(url, { signal: ctrl.signal, redirect: 'follow' });
        if (!res.ok)
            return null;
        const ct = (res.headers.get('content-type') || '').toLowerCase();
        if (ct.includes('text/html'))
            return null;
        const buf = Buffer.from(await res.arrayBuffer());
        if (buf.length < MIN_BYTES)
            return null;
        if (!looksLikeExecutable(buf))
            return null;
        return buf;
    }
    catch {
        return null;
    }
    finally {
        clearTimeout(timer);
    }
}
function buildCandidateUrls(owner, repo, version, assetName) {
    const v = version.startsWith('v') ? version : `v${version}`;
    return [`https://github.com/${owner}/${repo}/releases/download/${v}/${assetName}`];
}
/**
 * If a valid binary already exists in the user cache, return its path.
 * Otherwise try to download from the matching GitHub release tag.
 * Returns null if disabled, failed, or unsupported.
 */
export async function tryDownloadMk3Binary(packageRoot) {
    if (process.env.NO_MK3_DOWNLOAD === '1')
        return null;
    const binaryName = process.platform === 'win32' ? 'mk3-tui.exe' : 'mk3-tui';
    let pkg;
    try {
        const pkgPath = path.join(packageRoot, 'package.json');
        pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
    }
    catch {
        return null;
    }
    const version = pkg.version || '0.0.0';
    const dest = getVersionedMk3UserCachePath(binaryName, version);
    const override = process.env.MK3_TUI_DOWNLOAD_URL?.trim();
    if (override) {
        process.stderr.write('\n[4Runr] Downloading mk3-tui (MK3_TUI_DOWNLOAD_URL)...\n');
        const buf = await fetchUrlToBuffer(override);
        if (buf) {
            writeBinaryAtomic(dest, buf);
            return dest;
        }
        process.stderr.write('[4Runr] Download from MK3_TUI_DOWNLOAD_URL failed.\n');
        return null;
    }
    if (fs.existsSync(dest)) {
        try {
            const st = fs.statSync(dest);
            if (st.size >= MIN_BYTES)
                return dest;
        }
        catch {
            /* fall through to re-download */
        }
    }
    const gh = parseGithubRepo(pkg);
    if (!gh)
        return null;
    const names = releaseAssetNames(binaryName);
    process.stderr.write('\n[4Runr] No local mk3-tui binary. Downloading pre-built TUI (one-time)...\n');
    for (const assetName of names) {
        const urls = buildCandidateUrls(gh.owner, gh.repo, version, assetName);
        for (const url of urls) {
            const buf = await fetchUrlToBuffer(url);
            if (buf) {
                writeBinaryAtomic(dest, buf);
                process.stderr.write(`[4Runr] Saved mk3-tui to ${dest}\n`);
                return dest;
            }
        }
    }
    process.stderr.write('[4Runr] Pre-built download not available (no matching GitHub release asset).\n');
    process.stderr.write('        You can build with Rust, or set MK3_TUI_DOWNLOAD_URL to a direct file URL.\n');
    return null;
}
function writeBinaryAtomic(dest, buf) {
    const dir = path.dirname(dest);
    fs.mkdirSync(dir, { recursive: true });
    const tmp = `${dest}.${process.pid}.tmp`;
    fs.writeFileSync(tmp, buf);
    if (process.platform !== 'win32') {
        try {
            fs.chmodSync(tmp, 0o755);
        }
        catch {
            /* ignore */
        }
    }
    fs.renameSync(tmp, dest);
}
//# sourceMappingURL=mk3-binary-bootstrap.js.map