/**
 * olam restart <world> — Restart a world container, auto-building the
 * agent-stream bundle first when the host dist is stale.
 *
 * Phase B2 (olam-world-bundle-freshness): closes the silent-staleness
 * loop where operators run `olam restart` expecting a fresh bundle but
 * instead get the image-baked dist from the last docker build.
 *
 * With Phase B1's bind-mount overlay, the freshly-built dist is
 * immediately visible inside the restarted container — no docker cp
 * required.
 *
 * Fast path (dist current): ≤ 15s.
 * Slow path (dist absent or stale): ≤ 90s (dominated by tsc compile).
 */
import { existsSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { spawnSync } from 'node:child_process';
import { loadContext } from '../context.js';
import { printError, printInfo, printHeader } from '../output.js';
import { buildIfStale } from '../lib/build-if-stale.js';
import { resolveBundleSource, BundleSourceNotFoundError } from '../lib/bundle-source.js';
const RESTART_TIMEOUT_S = 30;
function docker(args) {
    const result = spawnSync('docker', args, {
        encoding: 'utf-8',
        stdio: ['ignore', 'pipe', 'pipe'],
    });
    return {
        ok: result.status === 0 && result.error === undefined,
        stderr: result.stderr ?? '',
    };
}
/**
 * Walk up from `start` until we find a directory containing both
 * `packages/` and `package.json`. Returns `start` if not found.
 */
function resolveRepoRoot(start) {
    let cur = start;
    while (true) {
        if (existsSync(resolve(cur, 'packages')) && existsSync(resolve(cur, 'package.json'))) {
            return cur;
        }
        const parent = dirname(cur);
        if (parent === cur)
            return start;
        cur = parent;
    }
}
export function registerRestart(program) {
    program
        .command('restart')
        .description('Restart a world container (auto-builds agent-stream bundle when stale)')
        .argument('<world>', 'World ID or name')
        .action(async (worldIdOrName) => {
        const { ctx, error } = await loadContext();
        if (!ctx) {
            printError(error?.message ?? 'Olam is not configured. Run `olam init` first.');
            process.exitCode = 1;
            return;
        }
        const world = ctx.worldManager.getWorld(worldIdOrName);
        if (!world) {
            printError(`World "${worldIdOrName}" not found. Run \`olam list\` to see worlds.`);
            process.exitCode = 1;
            return;
        }
        printHeader(`olam restart: ${world.name}`);
        // C3 (olam-world-bundle-freshness): resolve bundle source and branch on mode.
        // source-mode: auto-build if stale (B2 path).
        // install-mode: skip build, log one line, proceed immediately.
        try {
            const bundleSource = resolveBundleSource();
            if (bundleSource.mode === 'install') {
                // C3 acceptance: log exactly this line to stderr.
                process.stderr.write('bundle source: install-mode; skipping rebuild\n');
            }
            else {
                // source-mode: B2 path — auto-build if stale.
                const repoRoot = resolveRepoRoot(process.cwd());
                const buildResult = buildIfStale(repoRoot);
                if (!buildResult.ok) {
                    printError('Agent-stream bundle build failed. Not restarting with a stale bundle.\n' +
                        'Fix the build error and re-run `olam restart`.');
                    process.exitCode = 1;
                    return;
                }
                printInfo('Bundle', buildResult.message);
            }
        }
        catch (err) {
            if (err instanceof BundleSourceNotFoundError) {
                // Graceful degradation: bundle path unresolved, but still restart.
                // The container uses its image-baked dist as fallback.
                process.stderr.write(`Warning: agent-stream bundle path unresolved; container uses image-baked dist.\n`);
            }
            else {
                throw err;
            }
        }
        // Restart the container.
        const containerName = `olam-${world.id}-devbox`;
        printInfo('Container', containerName);
        const result = docker(['restart', '--time', String(RESTART_TIMEOUT_S), containerName]);
        if (!result.ok) {
            printError(`docker restart failed: ${result.stderr.trim() || '(no stderr)'}`);
            process.exitCode = 1;
            return;
        }
        printInfo('Status', 'restarted');
    });
}
//# sourceMappingURL=restart.js.map