/**
 * Smoke test for a WSL2 sandbox distro.
 *
 * Verifies that all expected binaries and Python packages are available.
 */
import { spawn } from 'child_process';
/** Binaries that must exist in the distro. */
const REQUIRED_BINARIES = ['bwrap', 'bash', 'python3', 'pip', 'curl', 'socat'];
/** Python packages that must be importable. */
const REQUIRED_PYTHON_PACKAGES = ['openpyxl', 'httpx'];
/** Run a smoke test against the sandbox distro. */
export async function runSandboxSmokeTestAsync(distro) {
    const output = await runBatchedSmokeAsync(distro);
    return parseSmokeTestOutput(output);
}
function buildSmokeScript() {
    const binaryChecks = REQUIRED_BINARIES.map((bin) => `_p=$(which ${bin} 2>/dev/null) && echo "bin:${bin}:$_p:OK" || echo "bin:${bin}::FAIL"`);
    const pythonChecks = REQUIRED_PYTHON_PACKAGES.map((pkg) => `_v=$(python3 -c 'import ${pkg}; print(${pkg}.__version__)' 2>/dev/null) && echo "py:${pkg}:$_v:OK" || echo "py:${pkg}::FAIL"`);
    return [...binaryChecks, ...pythonChecks].join('; ');
}
function parseSmokeTestOutput(output) {
    const checks = [];
    const lines = output.split('\n').filter(Boolean);
    const expectedBins = new Set(REQUIRED_BINARIES);
    const expectedPkgs = new Set(REQUIRED_PYTHON_PACKAGES);
    for (const line of lines) {
        const match = line.match(/^(bin|py):([^:]+):(.*?):(OK|FAIL)\s*$/);
        if (!match)
            continue;
        const [, type, name, detail, status] = match;
        const isOk = status === 'OK';
        if (type === 'bin') {
            expectedBins.delete(name);
            checks.push({ name: name, ok: isOk, detail: isOk ? detail || name : 'not found' });
        }
        else {
            expectedPkgs.delete(name);
            checks.push({ name: `python:${name}`, ok: isOk, detail: isOk ? detail : 'import failed' });
        }
    }
    for (const bin of expectedBins) {
        checks.push({ name: bin, ok: false, detail: 'not found' });
    }
    for (const pkg of expectedPkgs) {
        checks.push({ name: `python:${pkg}`, ok: false, detail: 'import failed' });
    }
    return { ok: checks.every((c) => c.ok), checks };
}
function runBatchedSmokeAsync(distro) {
    const script = buildSmokeScript();
    return new Promise((resolve) => {
        const child = spawn('wsl', ['-d', distro, '--', 'sh', '-c', script], {
            stdio: ['ignore', 'pipe', 'pipe'],
            windowsHide: true
        });
        let output = '';
        let settled = false;
        child.stdout?.on('data', (chunk) => {
            output += chunk.toString();
        });
        child.stderr?.on('data', (chunk) => {
            output += chunk.toString();
        });
        child.on('error', () => {
            if (!settled) {
                settled = true;
                clearTimeout(timer);
                resolve(output);
            }
        });
        const timer = setTimeout(() => {
            if (!settled) {
                settled = true;
                child.kill();
                resolve(output);
            }
        }, 15_000);
        child.on('close', () => {
            if (!settled) {
                settled = true;
                clearTimeout(timer);
                resolve(output);
            }
        });
    });
}
//# sourceMappingURL=smoke.js.map