/**
 * Shared pre-flight logic for Unix-like platforms (macOS + Linux).
 *
 * Both platforms follow the same uv → Python → packages → sheet engine flow.
 * The only differences are:
 * - uv download URL (apple-darwin vs unknown-linux-gnu)
 * - Chrome detection paths
 *
 * Platform modules (mac.ts, linux.ts) call these with the appropriate target
 * and provide their own Chrome detection.
 */
import { chmodSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
import { dirname, join } from 'path';
import { getSettingsPath, getUvBinPath, getUvPythonDir, getUvVenvDir, VERSION } from '../../config.js';
import { UV_PIP_PACKAGES, UV_PYTHON_VERSION, UV_VERSION } from '../../constants.js';
import { run } from '../install-utils.js';
import { header, log, note, ok, runWithProgress } from './utils.js';
// ── uv download ─────────────────────────────────────────────────────────
/**
 * Download the uv binary from Astral's GitHub releases.
 * uv is ~25 MB and provides Python installation + package management.
 *
 * @param platformTarget - The platform target string for the uv download URL
 *   (e.g., 'apple-darwin' for macOS, 'unknown-linux-gnu' for Linux).
 */
export async function ensureUv(platformTarget) {
    header('Python Toolchain');
    const uvPath = getUvBinPath();
    if (existsSync(uvPath)) {
        const check = run(`"${uvPath}" --version`, { timeout: 5_000 });
        if (check.ok) {
            ok(`uv ${check.stdout.replace('uv ', '').trim()} installed.`);
            return true;
        }
    }
    log('Downloading uv (Python toolchain)...', 'Setting up Python toolchain...');
    const arch = process.arch === 'arm64' ? 'aarch64' : 'x86_64';
    const url = `https://github.com/astral-sh/uv/releases/download/${UV_VERSION}/uv-${arch}-${platformTarget}.tar.gz`;
    try {
        const uvDir = dirname(uvPath);
        mkdirSync(uvDir, { recursive: true });
        const response = await fetch(url, { signal: AbortSignal.timeout(60_000) });
        if (!response.ok || !response.body) {
            log('Shortcut agent will set up the Python toolchain.', 'Will finish setup automatically.');
            note(`uv download failed: HTTP ${response.status} from ${url}`);
            return false;
        }
        // uv releases are .tar.gz — pipe through tar to extract
        const tmpTarPath = `${uvPath}.tar.gz`;
        const arrayBuffer = await response.arrayBuffer();
        writeFileSync(tmpTarPath, Buffer.from(arrayBuffer));
        const extract = run(`tar -xzf "${tmpTarPath}" -C "${uvDir}" --strip-components=1`, {
            timeout: 30_000
        });
        try {
            unlinkSync(tmpTarPath);
        }
        catch {
            /* non-fatal */
        }
        if (!extract.ok) {
            log('Shortcut agent will set up the Python toolchain.', 'Will finish setup automatically.');
            note(`uv extract failed: ${extract.stderr}`);
            return false;
        }
        try {
            chmodSync(uvPath, 0o755);
        }
        catch {
            /* non-fatal */
        }
        const verify = run(`"${uvPath}" --version`, { timeout: 5_000 });
        if (verify.ok) {
            ok(`uv ${verify.stdout.replace('uv ', '').trim()} installed.`);
            return true;
        }
        log('Shortcut agent will verify the Python toolchain.', 'Will verify automatically.');
        return false;
    }
    catch (e) {
        log('Shortcut agent will set up the Python toolchain.', 'Will finish setup automatically.');
        note(e instanceof Error ? e.message : String(e));
        return false;
    }
}
// ── Python install via uv ───────────────────────────────────────────────
/**
 * Use uv to install Python and create a managed venv with required packages.
 */
export async function ensureUvPython() {
    header('Python', 'Python Runtime');
    const uvPath = getUvBinPath();
    const venvDir = getUvVenvDir();
    const venvPython = join(venvDir, 'bin', 'python3');
    // Check if venv already exists and works
    if (existsSync(venvPython)) {
        const check = run(`"${venvPython}" --version`, { timeout: 5_000 });
        if (check.ok) {
            ok(`${check.stdout.trim()} ready.`);
            return true;
        }
    }
    mkdirSync(getUvPythonDir(), { recursive: true });
    // Install Python via uv
    log('Installing Python...', 'Installing Python...');
    const installResult = await runWithProgress(`"${uvPath}" python install ${UV_PYTHON_VERSION}`, {
        timeout: 120_000,
        label: 'Installing Python'
    });
    if (!installResult.ok) {
        log('Shortcut agent will finish installing Python.', 'Will finish setup automatically.');
        note(`uv python install failed: ${installResult.stderr}`);
        return false;
    }
    // Create venv
    log('Creating Python environment...', 'Setting up environment...');
    const venvResult = run(`"${uvPath}" venv "${venvDir}" --python ${UV_PYTHON_VERSION}`, {
        timeout: 30_000
    });
    if (!venvResult.ok) {
        log('Shortcut agent will finish setting up Python.', 'Will finish setup automatically.');
        note(`uv venv failed: ${venvResult.stderr}`);
        return false;
    }
    ok('Python environment created.');
    return true;
}
// ── pip packages ────────────────────────────────────────────────────────
/**
 * Install required pip packages into the uv-managed venv.
 */
export async function ensureUvPackages() {
    header('Python Packages', 'Python Packages');
    const uvPath = getUvBinPath();
    const venvDir = getUvVenvDir();
    const venvPython = join(venvDir, 'bin', 'python3');
    if (!existsSync(venvPython)) {
        log('Shortcut agent will install packages after Python is ready.', 'Will finish setup automatically.');
        return;
    }
    // Check if packages are already installed via a stamp that includes the package list.
    // This ensures adding/removing a package triggers reinstall even without a version bump.
    const stampFile = join(venvDir, '.packages-stamp');
    const stampValue = `${VERSION}:${UV_PIP_PACKAGES.join(',')}`;
    try {
        if (existsSync(stampFile) && readFileSync(stampFile, 'utf-8').trim() === stampValue) {
            ok('Packages already installed.', 'Ready.');
            return;
        }
    }
    catch {
        /* proceed with install */
    }
    log('Installing packages...', 'Installing packages...');
    const pipResult = await runWithProgress(`"${uvPath}" pip install --python "${venvPython}" ${UV_PIP_PACKAGES.join(' ')}`, { timeout: 120_000, label: 'Installing' });
    if (pipResult.ok) {
        ok('Packages installed.', 'Ready.');
        try {
            writeFileSync(stampFile, stampValue, 'utf-8');
        }
        catch {
            /* non-fatal */
        }
    }
    else {
        log('Shortcut agent will finish installing packages.', 'Will finish setup automatically.');
        note(`uv pip install failed: ${pipResult.stderr}`);
    }
}
// ── Sheet engine ────────────────────────────────────────────────────────
export function ensureNewSheet() {
    header('Sheet Engine');
    // No Excel COM/XLL on Unix — enable the headless Rust sheet engine.
    const settingsPath = getSettingsPath();
    let settings = {};
    try {
        settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
    }
    catch {
        // No settings file yet — will create one
    }
    if (settings.newSheet === true) {
        ok('Headless sheet engine already enabled.');
        return;
    }
    settings.newSheet = true;
    try {
        writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
        ok('Headless sheet engine enabled.');
    }
    catch (e) {
        log('Shortcut agent will enable the sheet engine.', 'Will finish setup automatically.');
        note(e instanceof Error ? e.message : String(e));
    }
}
/**
 * Smoke test the headless sheet engine.
 */
export function smokeTestSheetEngine() {
    header('Sheet Engine', 'Verifying Setup');
    try {
        // Subprocess intentional: @mog-sdk/node has native bindings with process-level
        // side effects (shared memory, worker threads). Importing it here would pollute
        // the preflight process and make cleanup impossible if the check fails.
        const check = run(`node -e "import('@mog-sdk/node').then(m => { if (m.api) process.exit(0); else process.exit(1); }).catch(() => process.exit(1))"`, { timeout: 10_000 });
        if (check.ok) {
            ok('Sheet engine verified.', 'Ready.');
            return true;
        }
        // Engine not available — not fatal, the agent can still work without it
        // (user just won't have spreadsheet functionality until it's resolved)
        log('Sheet engine not available — Shortcut agent will troubleshoot.', 'Will verify automatically.');
        return false;
    }
    catch {
        log('Sheet engine check skipped.', 'Will verify automatically.');
        return false;
    }
}
//# sourceMappingURL=shared.js.map