import { spawn } from 'node:child_process';
import { once } from 'node:events';
import net from 'node:net';

/** Launch the exact documented entry point; readiness is observed, never a fixed soak. */
export async function checkpoint(name) {
    const guard = net.createServer();
    await new Promise((resolve, reject) => { guard.once('error', reject); guard.listen(8181, resolve); });
    await new Promise(resolve => guard.close(resolve));
    const child = spawn(process.execPath, [`dist/${name}.js`], { stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });
    let output = '';
    child.stdout.on('data', data => { output += data; });
    child.stderr.on('data', data => { output += data; });
    const close = async () => {
        if (child.exitCode !== null || child.signalCode !== null) return;
        const stopped = once(child, 'exit');
        child.kill();
        await stopped;
    };
    const deadline = Date.now() + 8000;
    try {
        while (Date.now() < deadline) {
            if (child.exitCode !== null) throw new Error(output);
            try {
                const response = await fetch('http://localhost:8181', { signal: AbortSignal.timeout(300) });
                if (response.ok) return { origin: 'http://localhost:8181', close };
            } catch { /* Listener not ready yet. */ }
            await new Promise(resolve => setTimeout(resolve, 20));
        }
        throw new Error(`Checkpoint did not become ready: ${output}`);
    } catch (error) { await close(); throw error; }
}
