// 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); }
};
import { SoloError } from '../errors/solo-error.js';
import { Flags as flags } from '../../commands/flags.js';
import { inject, injectable } from 'tsyringe-neo';
import { InjectTokens } from '../dependency-injection/inject-tokens.js';
import { InitCommand } from '../../commands/init/init.js';
import { patchInject } from '../dependency-injection/container-helper.js';
import * as constants from '../constants.js';
let Subcommand = class Subcommand {
    name;
    description;
    commandHandlerClass;
    commandHandler;
    flags;
    dependencies;
    createCluster;
    initCommand;
    taskList;
    // TODO: Subcommand should have its own class file
    constructor(name, description, commandHandlerClass, commandHandler, flags, dependencies = [], createCluster = false, initCommand, taskList) {
        this.name = name;
        this.description = description;
        this.commandHandlerClass = commandHandlerClass;
        this.commandHandler = commandHandler;
        this.flags = flags;
        this.dependencies = dependencies;
        this.createCluster = createCluster;
        this.initCommand = initCommand;
        this.taskList = taskList;
        this.initCommand = patchInject(initCommand, InjectTokens.InitCommand, this.constructor.name);
        this.taskList = patchInject(taskList, InjectTokens.TaskList, this.constructor.name);
    }
    async installDependencies() {
        const tasks = this.taskList.newTaskList([
            ...this.initCommand.installDependenciesTasks({
                deps: this.dependencies,
                createCluster: this.createCluster,
            }),
        ], constants.LISTR_DEFAULT_OPTIONS.DEFAULT, undefined, this.name);
        if (this.taskList.parentTaskListMap.size === 0) {
            try {
                await tasks.run();
            }
            catch (error) {
                throw new SoloError(`Could not install dependencies: ${error.message}`, error);
            }
        }
    }
};
Subcommand = __decorate([
    injectable(),
    __param(7, inject(InjectTokens.InitCommand)),
    __param(8, inject(InjectTokens.TaskList)),
    __metadata("design:paramtypes", [String, String, Object, Function, Object, Array, Boolean, InitCommand, Object])
], Subcommand);
export { Subcommand };
// TODO: CommandGroup should have its own class file
export class CommandGroup {
    name;
    description;
    subcommands = [];
    constructor(name, description) {
        this.name = name;
        this.description = description;
    }
    addSubcommand(subcommand) {
        this.subcommands.push(subcommand);
        return this;
    }
}
// TODO: CommandBuilder should have its own class file
export class CommandBuilder {
    name;
    description;
    logger;
    commandGroups = [];
    constructor(name, description, logger) {
        this.name = name;
        this.description = description;
        this.logger = logger;
    }
    addCommandGroup(commandGroup) {
        this.commandGroups.push(commandGroup);
        return this;
    }
    build() {
        const commandGroups = this.commandGroups;
        const logger = this.logger;
        const commandName = this.name;
        const commandDescription = this.description;
        const demandCommand = `select a ${commandName} command`;
        return {
            command: commandName,
            desc: commandDescription,
            builder: (yargs) => {
                for (const commandGroup of commandGroups) {
                    yargs.command({
                        command: commandGroup.name,
                        desc: commandGroup.description,
                        builder: (yargs) => {
                            yargs.help(); // Enable help for command group level
                            for (const subcommand of commandGroup.subcommands) {
                                const handlerDefinition = {
                                    command: subcommand.name,
                                    desc: subcommand.description,
                                    handler: async (argv) => {
                                        const commandPath = `${commandName} ${commandGroup.name} ${subcommand.name}`;
                                        logger.info(`==== Running '${commandPath}' ===`);
                                        const handlerCallback = subcommand.commandHandler.bind(subcommand.commandHandlerClass);
                                        await subcommand.installDependencies();
                                        const response = await handlerCallback(argv);
                                        logger.info(`==== Finished running '${commandPath}'====`);
                                        if (!response) {
                                            throw new SoloError(`Error running ${commandPath}, expected return value to be true`);
                                        }
                                    },
                                };
                                if (subcommand.flags) {
                                    handlerDefinition.builder = (y) => {
                                        flags.setRequiredCommandFlags(y, ...subcommand.flags.required);
                                        flags.setOptionalCommandFlags(y, ...subcommand.flags.optional);
                                    };
                                }
                                yargs.command(handlerDefinition);
                            }
                            yargs.demandCommand(1, `Select a ${commandName} ${commandGroup.name} command`);
                            return yargs.help();
                        },
                    });
                }
                yargs.demandCommand(1, demandCommand);
                return yargs.help();
            },
        };
    }
}
//# sourceMappingURL=command-builder.js.map