// SPDX-License-Identifier: Apache-2.0
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var InitCommand_1;
import { BaseCommand } from '../base.js';
import fs from 'node:fs';
import * as constants from '../../core/constants.js';
import { SoloError } from '../../core/errors/solo-error.js';
import { Flags as flags } from '../flags.js';
import chalk from 'chalk';
import { PathEx } from '../../business/utils/path-ex.js';
import { inject, injectable } from 'tsyringe-neo';
import { InjectTokens } from '../../core/dependency-injection/inject-tokens.js';
import { patchInject } from '../../core/dependency-injection/container-helper.js';
import { BrewPackageManager } from '../../core/package-managers/brew-package-manager.js';
import { OsPackageManager } from '../../core/package-managers/os-package-manager.js';
import { ClusterTaskManager } from '../../core/cluster-task-manager.js';
/**
 * Defines the core functionalities of 'init' command
 */
let InitCommand = class InitCommand extends BaseCommand {
    static { InitCommand_1 = this; }
    kindBuilder;
    podmanInstallationDirectory;
    brewPackageManager;
    osPackageManager;
    clusterTaskManager;
    static COMMAND_NAME = 'init';
    static INIT_COMMAND_NAME = InitCommand_1.COMMAND_NAME;
    constructor(kindBuilder, podmanInstallationDirectory, brewPackageManager, osPackageManager, clusterTaskManager) {
        super();
        this.kindBuilder = kindBuilder;
        this.podmanInstallationDirectory = podmanInstallationDirectory;
        this.brewPackageManager = brewPackageManager;
        this.osPackageManager = osPackageManager;
        this.clusterTaskManager = clusterTaskManager;
        this.kindBuilder = patchInject(kindBuilder, InjectTokens.KindBuilder, InitCommand_1.name);
        this.brewPackageManager = patchInject(brewPackageManager, InjectTokens.BrewPackageManager, InitCommand_1.name);
        this.osPackageManager = patchInject(osPackageManager, InjectTokens.OsPackageManager, InitCommand_1.name);
        this.clusterTaskManager = patchInject(clusterTaskManager, InjectTokens.ClusterTaskManager, InitCommand_1.name);
        this.podmanInstallationDirectory = patchInject(podmanInstallationDirectory, InjectTokens.PodmanInstallationDir, InitCommand_1.name);
    }
    setupSystemFilesTasks(argv) {
        const self = this;
        let cacheDirectory = this.configManager.getFlag(flags.cacheDir);
        if (!cacheDirectory) {
            cacheDirectory = constants.SOLO_CACHE_DIR;
        }
        return [
            {
                title: 'Setup home directory and cache',
                task: async (context_, task) => {
                    self.configManager.update(argv);
                    context_.dirs = this.setupHomeDirectory();
                    let username = self.configManager.getFlag(flags.username);
                    if (username && !flags.username.validate(username)) {
                        username = await flags.username.prompt(task, username);
                    }
                    context_.config = { username };
                },
            },
            {
                title: 'Create local configuration',
                skip: () => this.localConfig.configFileExists(),
                task: async () => {
                    await this.localConfig.load();
                },
            },
            {
                title: `Copy templates in '${cacheDirectory}'`,
                task: context_ => {
                    let directoryCreated = false;
                    const resources = ['templates', 'profiles'];
                    for (const directoryName of resources) {
                        const sourceDirectory = PathEx.safeJoinWithBaseDirConfinement(constants.RESOURCES_DIR, constants.RESOURCES_DIR, directoryName);
                        if (!fs.existsSync(sourceDirectory)) {
                            continue;
                        }
                        const destinationDirectory = PathEx.join(cacheDirectory, directoryName);
                        if (!fs.existsSync(destinationDirectory)) {
                            directoryCreated = true;
                            fs.mkdirSync(destinationDirectory, { recursive: true });
                        }
                        fs.cpSync(sourceDirectory, destinationDirectory, { recursive: true });
                    }
                    if (argv.dev) {
                        self.logger.showList('Home Directories', context_.dirs);
                        self.logger.showList('Chart Repository', context_.repoURLs);
                    }
                    if (directoryCreated) {
                        self.logger.showUser(chalk.grey('\n***************************************************************************************'));
                        self.logger.showUser(chalk.grey(`Note: solo stores various artifacts (config, logs, keys etc.) in its home directory: ${constants.SOLO_HOME_DIR}\n` +
                            "If a full reset is needed, delete the directory or relevant sub-directories before running 'solo init'."));
                        self.logger.showUser(chalk.grey('***************************************************************************************'));
                    }
                },
            },
        ];
    }
    installDependenciesTasks(options) {
        const self = this;
        if (!options.deps || options.deps.length === 0) {
            return [];
        }
        const tasks = [
            {
                title: 'Check dependencies',
                task: (_, task) => {
                    const subTasks = self.depManager.taskCheckDependencies(options.deps);
                    // set up the sub-tasks
                    return task.newListr(subTasks, {
                        concurrent: true,
                        rendererOptions: {
                            collapseSubtasks: false,
                        },
                    });
                },
            },
        ];
        if (options.deps.includes(constants.HELM)) {
            tasks.push({
                title: 'Setup chart manager',
                task: async (context_) => {
                    context_.repoURLs = await this.chartManager.setup();
                },
            });
        }
        if (options.createCluster) {
            tasks.push(...this.clusterTaskManager.setupLocalClusterTasks());
        }
        return tasks;
    }
    /** Executes the init CLI command */
    initTasks(argv) {
        return this.taskList.newTaskList([
            ...this.setupSystemFilesTasks(argv),
            ...this.installDependenciesTasks({
                deps: [constants.HELM, constants.KUBECTL],
                createCluster: false,
            }),
        ], constants.LISTR_DEFAULT_OPTIONS.DEFAULT, undefined, InitCommand_1.INIT_COMMAND_NAME);
    }
    async init(argv) {
        const tasks = this.initTasks(argv);
        this.logger.showUser(chalk.grey('**********************************************************************************'));
        this.logger.showUser(chalk.grey("'solo init' is now deprecated, you don't need to run it anymore."));
        this.logger.showUser(chalk.grey('**********************************************************************************\n'));
        if (tasks.isRoot()) {
            try {
                await tasks.run();
            }
            catch (error) {
                throw new SoloError('Error running init', error);
            }
        }
        return true;
    }
    /**
     * Return Yargs command definition for 'init' command
     * @returns A object representing the Yargs command definition
     */
    getCommandDefinition() {
        const self = this;
        return {
            command: InitCommand_1.COMMAND_NAME,
            desc: 'Initialize local environment',
            builder: (y) => {
                // set the quiet flag even though it isn't used for consistency across all commands
                flags.setOptionalCommandFlags(y, flags.cacheDir, flags.quiet, flags.username);
            },
            handler: async (argv) => {
                await self
                    .init(argv)
                    .then(r => {
                    if (!r) {
                        throw new SoloError('Error running init, expected return value to be true');
                    }
                })
                    .catch(error => {
                    throw new SoloError('Error running init', error);
                });
            },
        };
    }
    close() {
        // no-op
        return Promise.resolve();
    }
};
InitCommand = InitCommand_1 = __decorate([
    injectable(),
    __param(0, inject(InjectTokens.KindBuilder)),
    __param(1, inject(InjectTokens.PodmanInstallationDir)),
    __param(2, inject(InjectTokens.BrewPackageManager)),
    __param(3, inject(InjectTokens.OsPackageManager)),
    __param(4, inject(InjectTokens.ClusterTaskManager)),
    __metadata("design:paramtypes", [Function, String, BrewPackageManager,
        OsPackageManager,
        ClusterTaskManager])
], InitCommand);
export { InitCommand };
//# sourceMappingURL=init.js.map