/**
 * olam destroy <world> — Tear down a world and clean up resources.
 *
 * Accepts a world ID (the long-standing contract) OR a world name —
 * operators usually remember the friendly name, not the generated id.
 * Resolution precedence is exact-ID-first, so existing scripts that pass
 * an ID keep their behaviour. On a miss, a "did you mean" hint surfaces
 * the closest worlds (typo / substring), mirroring `olam dispatch`. This
 * matters most here: destroy is irreversible, so a silent not-found that
 * forces the operator to re-run `olam list` and retype is a sharp edge.
 */
import ora from 'ora';
import pc from 'picocolors';
import { loadContext } from '../context.js';
import { printError } from '../output.js';
import { findHostCpContainer, callHostCpRegistry } from './host-cp.js';
import { resolveWorld, suggestWorlds } from './dispatch-resolve.js';
/**
 * Run the destroy command. Pure: all I/O happens through {@link DestroyDeps}.
 *
 * @returns Process exit code (0 success, 1 error).
 */
export async function runDestroy(worldArg, opts, deps) {
    const worlds = deps.listWorlds();
    // Accept either a world ID (existing contract — exact ID wins) or a name.
    const world = resolveWorld(worlds, worldArg);
    if (!world) {
        deps.stderr(`World "${worldArg}" not found.`);
        const suggestions = suggestWorlds(worlds, worldArg);
        if (suggestions.length > 0) {
            deps.stdout(pc.dim('\n  Did you mean:'));
            for (const s of suggestions) {
                deps.stdout(`    ${pc.bold(s.name)} ${pc.dim(`(${s.id})`)}  ${pc.dim(s.status)}`);
            }
        }
        deps.stdout(pc.dim('\n  Run `olam list` to see all worlds.'));
        return 1;
    }
    const worldId = world.id;
    const spinner = deps.startSpinner(`Destroying ${world.name}...`);
    try {
        await deps.destroyWorld(worldId, { skipCrystallize: opts.skipCrystallize });
        spinner.succeed(`Destroyed ${world.name} (${worldId})`);
        // Auto-deregister from host CP if it's running. Best-effort — a failed
        // deregister leaves a stale registry entry that resolves to a 502 the
        // next time the SPA fetches the world's data, which is non-fatal but ugly.
        await deps.deregister(worldId);
        return 0;
    }
    catch (err) {
        spinner.fail('Failed to destroy world');
        deps.stderr(err instanceof Error ? err.message : String(err));
        return 1;
    }
}
export function registerDestroy(program) {
    program
        .command('destroy')
        .description('Destroy a world and clean up resources (accepts world ID or name)')
        .argument('<world>', 'World ID or name')
        .option('--skip-crystallize', 'Skip thought crystallization')
        .action(async (worldArg, opts) => {
        const { ctx, error } = await loadContext();
        if (!ctx) {
            printError(error?.message ?? 'Olam is not configured. Run `olam init` first.');
            process.exitCode = 1;
            return;
        }
        const code = await runDestroy(worldArg, opts, {
            listWorlds: () => ctx.worldManager.listWorlds().map((w) => ({
                id: w.id,
                name: w.name,
                status: w.status,
            })),
            destroyWorld: (worldId, destroyOpts) => ctx.worldManager.destroyWorld(worldId, destroyOpts),
            deregister: async (worldId) => {
                try {
                    const hostCp = await findHostCpContainer();
                    if (hostCp && hostCp.state === 'running') {
                        await callHostCpRegistry('DELETE', { id: worldId });
                    }
                }
                catch {
                    // Docker unreachable / host-cp probe failed — silently skip.
                }
            },
            startSpinner: (text) => {
                const spinner = ora(text).start();
                return {
                    succeed: (t) => { spinner.succeed(t); },
                    fail: (t) => { spinner.fail(t); },
                };
            },
            stdout: (line) => console.error(line),
            stderr: (line) => printError(line),
        });
        if (code !== 0) {
            process.exitCode = code;
        }
    });
}
//# sourceMappingURL=destroy.js.map