"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const nest_app_1 = require("../../lib/nest-app");
const context_banner_1 = require("../../lib/context-banner");
const cli_observability_cluster_service_1 = require("../../services/cli-observability-cluster.service");
const cluster_node_scaling_service_1 = require("../../../../src/modules/infrastructure/clusters/services/cluster-node-scaling.service");
const cluster_storage_service_1 = require("../../../../src/modules/infrastructure/clusters/services/cluster-storage.service");
const cluster_capacity_service_1 = require("../../../../src/modules/infrastructure/clusters/services/cluster-capacity.service");
const prompts_1 = require("../../lib/prompts");
class EnvStorageExpand extends core_1.Command {
    async run() {
        const { flags } = await this.parse(EnvStorageExpand);
        (0, context_banner_1.printContextBanner)();
        const spinner = (0, ora_1.default)('Inspecting current storage...').start();
        try {
            const app = await (0, nest_app_1.getNestApp)();
            const observabilityService = app.get(cli_observability_cluster_service_1.CliObservabilityClusterService);
            const storageService = app.get(cluster_storage_service_1.ClusterStorageService);
            const capacityService = app.get(cluster_capacity_service_1.ClusterCapacityService);
            const scalingService = app.get(cluster_node_scaling_service_1.ClusterNodeScalingService);
            const cluster = await observabilityService.getObservabilityCluster();
            if (!cluster) {
                spinner.fail('No observability cluster found');
                return;
            }
            const storage = await storageService.getStatus(cluster.id);
            let plan;
            try {
                plan = await capacityService.getPlan(cluster.id);
            }
            catch (err) {
                this.warn(`Capacity plan unavailable (${err.message}). ` +
                    'Proceeding without per-GB cost estimate.');
            }
            spinner.succeed('Storage status retrieved');
            if (!storage.volume) {
                console.log(chalk_1.default.red('\n❌ Cluster has no Flui-managed shared-storage volume to expand.\n'));
                this.exit(1);
            }
            const currentSize = storage.volume.sizeGb;
            const targetSize = flags.size ?? currentSize + 10;
            if (targetSize <= currentSize) {
                console.log(chalk_1.default.red(`\n❌ Target size (${targetSize} GB) must be greater than current (${currentSize} GB). Volumes cannot shrink.\n`));
                this.exit(1);
            }
            if (flags.size === undefined) {
                const label = `${targetSize} GB`;
                console.log(chalk_1.default.dim(`   (auto-selected target size: ${chalk_1.default.bold(label)} = current + 10 GB)`));
            }
            const deltaGb = targetSize - currentSize;
            const pricePerGb = plan?.storage?.pricePerGbMonthlyEur;
            const monthlyDelta = pricePerGb
                ? (Number.parseFloat(pricePerGb) * deltaGb).toFixed(2)
                : null;
            console.log(chalk_1.default.cyan('\n💾 Expand Shared Volume Plan\n'));
            console.log(`   ${chalk_1.default.bold('Cluster:')}    ${cluster.name}`);
            console.log(`   ${chalk_1.default.bold('Volume:')}     ${storage.volume.volumeId}`);
            console.log(`   ${chalk_1.default.bold('From:')}       ${currentSize} GB → ${targetSize} GB (+${deltaGb} GB)`);
            if (monthlyDelta) {
                console.log(`   ${chalk_1.default.bold('Cost:')}       +€${monthlyDelta}/month (€${pricePerGb}/GB)`);
            }
            console.log(`   ${chalk_1.default.bold('Downtime:')}   none (online ext4 resize)`);
            if (!flags.confirm) {
                console.log('');
                console.log(chalk_1.default.yellow(`   To confirm, type the cluster name exactly: ${chalk_1.default.bold(cluster.name)}`));
                const ok = await (0, prompts_1.confirmByTypingPrompt)(chalk_1.default.yellow('⚠️  Cluster name'), cluster.name);
                if (!ok) {
                    console.log(chalk_1.default.green('\n✅ Cancelled\n'));
                    return;
                }
            }
            const run = (0, ora_1.default)({
                text: `Expanding volume to ${targetSize} GB...`,
                color: 'yellow',
            }).start();
            try {
                const op = await scalingService.expandSharedVolume(cluster.id, {
                    targetSizeGb: targetSize,
                });
                run.succeed(`Volume expanded. Operation ${op.id} → ${op.status}`);
                if (op.metadata?.fsResizeWarning) {
                    console.log(chalk_1.default.yellow(`   ⚠️  Filesystem resize warning: ${op.metadata.fsResizeWarning}`));
                }
            }
            catch (error) {
                run.fail('Volume expand failed');
                throw error;
            }
            console.log('');
        }
        catch (error) {
            console.log(chalk_1.default.red('\n❌ Error:\n'));
            console.log(`   ${error instanceof Error ? error.message : String(error)}\n`);
            this.exit(1);
        }
        finally {
            await (0, nest_app_1.closeNestApp)();
        }
    }
}
EnvStorageExpand.description = 'Grow the cluster shared-storage backing Volume. Resizes the provider Volume, ' +
    'then runs resize2fs over SSH on the master so the new space is usable. ' +
    'Online for ext4 — no downtime expected. Volumes can only grow.';
EnvStorageExpand.examples = [
    '<%= config.bin %> <%= command.id %> --size 50',
    '<%= config.bin %> <%= command.id %> --size 100 --confirm',
];
EnvStorageExpand.flags = {
    size: core_1.Flags.integer({
        char: 's',
        description: 'New volume size in GB (must be greater than current). If omitted, defaults to current + 10 GB.',
    }),
    confirm: core_1.Flags.boolean({
        description: 'Skip the typed confirmation prompt',
        default: false,
    }),
};
exports.default = EnvStorageExpand;
