/**
 * Copyright (C) 2024 Hedera Hashgraph, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the ""License"");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an ""AS IS"" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import { Listr } from 'listr2';
import { SoloError } from '../core/errors.js';
import { BaseCommand } from './base.js';
import { Flags as flags } from './flags.js';
import * as constants from '../core/constants.js';
import { Templates } from '../core/templates.js';
import chalk from 'chalk';
import { RemoteConfigTasks } from '../core/config/remote/remote_config_tasks.js';
import { ListrLease } from '../core/lease/listr_lease.js';
export class DeploymentCommand extends BaseCommand {
    static get DEPLOY_FLAGS_LIST() {
        return [
            flags.quiet,
            flags.namespace,
            flags.userEmailAddress,
            flags.deploymentClusters,
            flags.contextClusterUnparsed,
        ];
    }
    async create(argv) {
        const self = this;
        const lease = await self.leaseManager.create();
        const tasks = new Listr([
            {
                title: 'Initialize',
                task: async (ctx, task) => {
                    self.configManager.update(argv);
                    self.logger.debug('Updated config with argv', { config: self.configManager.config });
                    await self.configManager.executePrompt(task, [
                        flags.contextClusterUnparsed,
                        flags.namespace,
                        flags.deploymentClusters,
                    ]);
                    ctx.config = {
                        contextClusterUnparsed: self.configManager.getFlag(flags.contextClusterUnparsed),
                        namespace: self.configManager.getFlag(flags.namespace),
                    };
                    ctx.config.contextCluster = Templates.parseContextCluster(ctx.config.contextClusterUnparsed);
                    const namespace = ctx.config.namespace;
                    if (!(await self.k8.hasNamespace(namespace))) {
                        await self.k8.createNamespace(namespace);
                    }
                    self.logger.debug('Prepared config', { config: ctx.config, cachedConfig: self.configManager.config });
                    return ListrLease.newAcquireLeaseTask(lease, task);
                },
            },
            this.localConfig.promptLocalConfigTask(self.k8),
            {
                title: 'Validate cluster connections',
                task: async (ctx, task) => {
                    const subTasks = [];
                    for (const cluster of Object.keys(ctx.config.contextCluster)) {
                        subTasks.push({
                            title: `Testing connection to cluster: ${chalk.cyan(cluster)}`,
                            task: async (_, task) => {
                                if (!(await self.k8.testClusterConnection(cluster))) {
                                    task.title = `${task.title} - ${chalk.red('Cluster connection failed')}`;
                                    throw new SoloError(`Cluster connection failed for: ${cluster}`);
                                }
                            },
                        });
                    }
                    return task.newListr(subTasks, {
                        concurrent: true,
                        rendererOptions: { collapseSubtasks: false },
                    });
                },
            },
            RemoteConfigTasks.createRemoteConfig.bind(this)(),
        ], {
            concurrent: false,
            rendererOptions: constants.LISTR_DEFAULT_RENDERER_OPTION,
        });
        try {
            await tasks.run();
        }
        catch (e) {
            throw new SoloError(`Error installing chart ${constants.SOLO_DEPLOYMENT_CHART}`, e);
        }
        finally {
            await lease.release();
        }
        return true;
    }
    getCommandDefinition() {
        const self = this;
        return {
            command: 'deployment',
            desc: 'Manage solo network deployment',
            builder: (yargs) => {
                return yargs
                    .command({
                    command: 'create',
                    desc: 'Creates solo deployment',
                    builder: (y) => flags.setCommandFlags(y, ...DeploymentCommand.DEPLOY_FLAGS_LIST),
                    handler: (argv) => {
                        self.logger.info("==== Running 'deployment create' ===");
                        self.logger.info(argv);
                        self
                            .create(argv)
                            .then(r => {
                            self.logger.info('==== Finished running `deployment create`====');
                            if (!r)
                                process.exit(1);
                        })
                            .catch(err => {
                            self.logger.showUserError(err);
                            process.exit(1);
                        });
                    },
                })
                    .demandCommand(1, 'Select a chart command');
            },
        };
    }
    close() {
        // no-op
        return Promise.resolve();
    }
}
//# sourceMappingURL=deployment.js.map