// B5 — `olam plans` subcommand surface.
//
//   olam plans list                            # list operator's plans
//   olam plans show <plan-id>                  # plan metadata + cost
//   olam plans rm <plan-id>                    # destroy (confirms active)
//   olam plans pin <plan-id> --days <n>        # exempt from TTL (queued)
//   olam plans unpin <plan-id>                 # release pin (queued)
//   olam plans re-register <plan-id> --token <ct>   # T6 recovery
//
// Operator identity: --operator <id> flag OR $OLAM_OPERATOR_ID env.
// Defaults to '$OLAM_OPERATOR_ID || "default"' — single-operator dogfood
// path. Multi-operator support follows the A11 vault-sync flow.
import { PlansClient, PlansClientError, resolveCloudConfig } from '../lib/plans-client.js';
import { printError, printSuccess, printHeader, printWarning } from '../output.js';
function defaultOperatorId() {
    return process.env.OLAM_OPERATOR_ID ?? 'default';
}
function makeClient() {
    const cfg = resolveCloudConfig();
    if (!cfg) {
        printError('Olam Cloud not configured. Set OLAM_CLOUD_URL (e.g. https://olam-plan-agent.<account>.workers.dev) ' +
            'and OLAM_SHOWCASE_PASSWORD, OR write them to ~/.olam/cloud-url + ~/.olam/showcase-password.');
        process.exit(2);
    }
    return new PlansClient(cfg);
}
function formatPlanRow(plan) {
    const lastActive = plan.last_active_at
        ? new Date(plan.last_active_at).toISOString().replace('T', ' ').slice(0, 16)
        : 'never';
    const pinFlag = plan.pinned_until ? ' [pinned]' : '';
    return `  ${plan.plan_id.padEnd(36)}  ${plan.status.padEnd(10)}  ${plan.mode.padEnd(6)}  ${lastActive}${pinFlag}`;
}
export function registerPlans(program) {
    const plans = program.command('plans').description('Manage Olam Cloud plans (list / show / rm / re-register)');
    plans
        .command('list')
        .description('List your cloud plans')
        .option('--operator <id>', 'Operator id', defaultOperatorId())
        .action(async (opts) => {
        const client = makeClient();
        try {
            const rows = await client.list(opts.operator);
            if (rows.length === 0) {
                printHeader(`No cloud plans for operator '${opts.operator}'.`);
                return;
            }
            printHeader(`${rows.length} plan(s) for operator '${opts.operator}':`);
            // eslint-disable-next-line no-console
            console.log('  ' + 'plan_id'.padEnd(36) + '  ' + 'status'.padEnd(10) +
                '  ' + 'mode'.padEnd(6) + '  ' + 'last_active_at');
            for (const row of rows) {
                // eslint-disable-next-line no-console
                console.log(formatPlanRow(row));
            }
        }
        catch (err) {
            printError(`list failed: ${err instanceof Error ? err.message : String(err)}`);
            process.exit(1);
        }
    });
    plans
        .command('show <plan-id>')
        .description('Show plan details')
        .option('--operator <id>', 'Operator id', defaultOperatorId())
        .action(async (planId, opts) => {
        const client = makeClient();
        try {
            const row = await client.show(planId, opts.operator);
            // eslint-disable-next-line no-console
            console.log(JSON.stringify(row, null, 2));
        }
        catch (err) {
            if (err instanceof PlansClientError && err.status === 404) {
                printError(`plan '${planId}' not found (or not yours).`);
                process.exit(1);
            }
            printError(`show failed: ${err instanceof Error ? err.message : String(err)}`);
            process.exit(1);
        }
    });
    plans
        .command('rm <plan-id>')
        .description('Destroy a plan (confirms when active)')
        .option('--operator <id>', 'Operator id', defaultOperatorId())
        .option('--force', 'Skip the active-plan confirmation prompt', false)
        .action(async (planId, opts) => {
        const client = makeClient();
        try {
            if (!opts.force) {
                try {
                    const row = await client.show(planId, opts.operator);
                    if (row.status === 'active') {
                        printWarning(`plan '${planId}' is ACTIVE. Re-run with --force to destroy, or wait for halt/destruction.`);
                        process.exit(2);
                    }
                }
                catch (err) {
                    if (!(err instanceof PlansClientError) || err.status !== 404)
                        throw err;
                    // 404 = nothing to confirm; remove() will no-op
                }
            }
            await client.remove(planId, opts.operator);
            printSuccess(`plan '${planId}' destroyed.`);
        }
        catch (err) {
            printError(`rm failed: ${err instanceof Error ? err.message : String(err)}`);
            process.exit(1);
        }
    });
    plans
        .command('pin <plan-id>')
        .description('Pin a plan to skip TTL pruner (queued — B5+ wires the endpoint)')
        .option('--operator <id>', 'Operator id', defaultOperatorId())
        .option('--days <n>', 'How many days to pin for', '30')
        .action(async (planId, opts) => {
        const client = makeClient();
        const days = Number.parseInt(opts.days, 10);
        if (!Number.isFinite(days) || days <= 0) {
            printError('--days must be a positive integer');
            process.exit(2);
        }
        const pinnedUntil = Date.now() + days * 24 * 60 * 60 * 1000;
        try {
            await client.pin(planId, opts.operator, pinnedUntil);
            printSuccess(`plan '${planId}' pinned until ${new Date(pinnedUntil).toISOString()}`);
        }
        catch (err) {
            printError(`pin failed: ${err instanceof Error ? err.message : String(err)}`);
            process.exit(1);
        }
    });
    plans
        .command('unpin <plan-id>')
        .description('Release a plan pin (queued — B5+ wires the endpoint)')
        .option('--operator <id>', 'Operator id', defaultOperatorId())
        .action(async (planId, opts) => {
        const client = makeClient();
        try {
            await client.unpin(planId, opts.operator);
            printSuccess(`plan '${planId}' unpinned.`);
        }
        catch (err) {
            printError(`unpin failed: ${err instanceof Error ? err.message : String(err)}`);
            process.exit(1);
        }
    });
    // C6 admin --aggregate subcommand. Requires both showcase Basic
    // auth (relay layer at plan-DO) AND ROTATE_SALT_ADMIN_SECRET
    // (auth-Worker handler layer). Used for gate #3 measurement:
    // ≥3 operators × ≥5 plans each.
    const admin = plans.command('admin').description('Admin operations (require admin secret)');
    admin
        .command('aggregate')
        .description('Aggregate plan stats by operator (gate #3 measurement)')
        .option('--admin-secret <s>', 'ROTATE_SALT_ADMIN_SECRET (or $OLAM_ADMIN_SECRET)')
        .option('--json', 'Output raw JSON instead of the table view', false)
        .action(async (opts) => {
        const client = makeClient();
        const adminSecret = opts.adminSecret ?? process.env.OLAM_ADMIN_SECRET ?? '';
        if (!adminSecret) {
            printError('--admin-secret or $OLAM_ADMIN_SECRET required.');
            process.exit(2);
        }
        try {
            const result = await client.adminAggregate(adminSecret);
            if (opts.json) {
                // eslint-disable-next-line no-console
                console.log(JSON.stringify(result, null, 2));
                return;
            }
            printHeader(`${result.count} operator(s):`);
            // eslint-disable-next-line no-console
            console.log('  ' + 'operator_id'.padEnd(22) +
                '  ' + 'plans'.padEnd(7) +
                '  ' + 'active'.padEnd(7) +
                '  ' + 'usd_lifetime'.padEnd(14) +
                '  ' + 'days_active');
            for (const op of result.operators) {
                const usd = `$${op.usd_lifetime.toFixed(2)}`;
                // eslint-disable-next-line no-console
                console.log('  ' + op.operator_id.padEnd(22) +
                    '  ' + String(op.plan_count).padEnd(7) +
                    '  ' + String(op.active_count).padEnd(7) +
                    '  ' + usd.padEnd(14) +
                    '  ' + op.days_active);
            }
        }
        catch (err) {
            printError(`aggregate failed: ${err instanceof Error ? err.message : String(err)}`);
            process.exit(1);
        }
    });
    plans
        .command('re-register <plan-id>')
        .description('Apply a Decision 15 confirmation_token to re-register a halted plan')
        .requiredOption('--token <ct>', 'confirmation_token from the recovery channel')
        .action(async (planId, opts) => {
        const client = makeClient();
        try {
            await client.reregister(planId, opts.token);
            printSuccess(`plan '${planId}' re-registered; status=active.`);
        }
        catch (err) {
            printError(`re-register failed: ${err instanceof Error ? err.message : String(err)}`);
            process.exit(1);
        }
    });
}
//# sourceMappingURL=plans.js.map