"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const _ = require("lodash");
const command_base_exec_1 = require("../../../command-base-exec");
class CabinetClusterAttach extends command_base_exec_1.CommandBaseExec {
    captureArgs() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { flags } = yield this.parse(CabinetClusterAttach);
            let partial = {};
            if (flags.enterprise)
                partial.enterprise = flags.enterprise;
            if (flags.cabinet)
                partial.cabinet = flags.cabinet;
            if (flags.environment)
                partial.environment = flags.environment;
            if (flags.cluster)
                partial.cluster = flags.cluster;
            if (flags.force)
                partial.force = flags.force;
            const takeDefaults = flags['take-defaults'];
            return [partial, takeDefaults];
        });
    }
    buildCandidate_silently(partial, rootMap) {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!partial.cabinet || _.isEmpty(partial.cabinet))
                throw new Error("Missing --cabinet argument.");
            if (!partial.environment || _.isEmpty(partial.environment))
                throw new Error("Missing --environment argument.");
            if (!partial.cluster || _.isEmpty(partial.cluster))
                throw new Error("Missing --cluster argument.");
            const ent = rootMap.enterprises.find(e => e.name === partial.enterprise);
            if (!ent)
                throw new Error(`Enterprise [${partial.enterprise}] was not found.`);
            const env = ent.environments.find(e => e.name === partial.environment);
            if (!env)
                throw new Error(`Environment [${partial.environment}] was not found.`);
            const cab = env.cabinets.find(c => c.name === partial.cabinet);
            if (!cab)
                throw new Error(`Cabinet [${partial.cabinet}] was not found.`);
            if (partial.force) {
                const cluster = (_a = rootMap.clusters) === null || _a === void 0 ? void 0 : _a.find(c => c.name === partial.cluster);
                if (!cluster)
                    throw new Error(`Cluster [${partial.cluster}] was not found.`);
            }
            else {
                const clusterInEnv = ((_b = env.clusters) !== null && _b !== void 0 ? _b : []).find(c => c.name === partial.cluster);
                if (!clusterInEnv)
                    throw new Error(`Cluster [${partial.cluster}] is not attached to environment [${partial.environment}]. Use --force to attach it automatically.`);
            }
            return {
                enterprise: partial.enterprise,
                cabinet: partial.cabinet,
                environment: partial.environment,
                cluster: partial.cluster,
                force: partial.force,
            };
        });
    }
    buildCandidate_interactively(partial, rootMap, takeDefaults) {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const ent = rootMap.enterprises.find(e => e.name === partial.enterprise);
            if (!ent)
                throw new Error(`Enterprise [${partial.enterprise}] was not found.`);
            const [cab] = yield this.rootMapUtils.promptForCabinet(ent.name, rootMap, partial.cabinet, takeDefaults, this.rootMapUtils.clusterLabelEmbellisher(), partial.cabinet);
            const env = ent.environments.find(e => e.name === cab.environment);
            // SELECT CLUSTER — without force, show only clusters already attached to the cabinet's environment
            if (!partial.cluster) {
                const candidateClusters = partial.force ? ((_a = rootMap.clusters) !== null && _a !== void 0 ? _a : []) : ((_b = env === null || env === void 0 ? void 0 : env.clusters) !== null && _b !== void 0 ? _b : []);
                if (candidateClusters.length === 0) {
                    if (partial.force)
                        throw new Error("No clusters found.");
                    throw new Error(`No clusters are attached to environment [${cab.environment}]. Use --force to select any cluster and attach it to the environment automatically.`);
                }
                const clusterChoices = candidateClusters.map(c => ({ name: c.name, value: c.name }));
                partial.cluster = (yield this._ui.promptSelect("cluster", "Attach to Cluster: ", clusterChoices, false, false));
            }
            return {
                enterprise: cab.enterprise,
                cabinet: cab.name,
                environment: cab.environment,
                cluster: partial.cluster,
                force: partial.force,
            };
        });
    }
    buildCommandString(candidate, cmd) {
        cmd.push("--enterprise", candidate.enterprise);
        cmd.push("--cabinet", candidate.cabinet);
        cmd.push("--environment", candidate.environment);
        cmd.push("--cluster", candidate.cluster);
        if (candidate.force)
            cmd.push("--force");
        cmd.push("--silent");
        return cmd;
    }
    executeTask(candidate) {
        var _a, _b, _c, _d, _e;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const result = yield this._codiacApi.Call.CabinetClusterAttach({
                cluster: candidate.cluster,
                cabinets: [{ cabinet: candidate.cabinet, enterprise: candidate.enterprise, environment: candidate.environment }],
                force: candidate.force,
            });
            if (result.error)
                throw result.error;
            const failures = (_a = result.failures) !== null && _a !== void 0 ? _a : [];
            if (failures.length > 0) {
                this._ui.userMessage(`${this._styler.colorCritical("FAILED!")} ${(_d = (_c = (_b = failures[0]) === null || _b === void 0 ? void 0 : _b.message) !== null && _c !== void 0 ? _c : result.message) !== null && _d !== void 0 ? _d : "Attach failed."}`);
                return;
            }
            if (result.success) {
                this._ui.userMessage(this._styler.colorGood("Success! ").concat(`Cabinet [${this._styler.hilite(candidate.cabinet)}] attached to cluster [${this._styler.hilite(candidate.cluster)}].`));
            }
            else {
                this._ui.userMessage((_e = result.message) !== null && _e !== void 0 ? _e : "Operation failed without error (Check log for details).");
            }
        });
    }
}
exports.default = CabinetClusterAttach;
CabinetClusterAttach.description = 'Declares which cluster a cabinet is intended to run on. Records the association in Codiac metadata so that restore and deploy operations know where to target the cabinet. No infrastructure is created or modified.';
CabinetClusterAttach.aliases = ["cab:cluster:attach", "cabinet:attach", "cab:attach"];
CabinetClusterAttach.examples = [
    { description: 'Attach a cabinet to a cluster interactively.', command: '<%= config.bin %> <%= command.id %>' },
    { description: 'Attach a specific cabinet to a cluster (prompts for missing values).', command: '<%= config.bin %> <%= command.id %> --enterprise acme --cabinet api-gateway --environment prod --cluster prod-cluster-1' },
    { description: 'Non-interactive (scripted) invocation — fails fast on any missing argument.', command: '<%= config.bin %> <%= command.id %> --enterprise acme --cabinet api-gateway --environment prod --cluster prod-cluster-1 --silent' },
    { description: 'Attach a cabinet to a cluster that is not yet in its environment, attaching the cluster to the environment automatically.', command: '<%= config.bin %> <%= command.id %> --enterprise acme --cabinet api-gateway --environment prod --cluster prod-cluster-1 --force' },
    { description: 'Renders the equivalent silent command and then executes (useful for building scripts).', command: '<%= config.bin %> <%= command.id %> --enterprise acme --cabinet api-gateway --environment prod --cluster prod-cluster-1 --echo' },
    { description: 'Renders the equivalent silent command without executing (dry run).', command: '<%= config.bin %> <%= command.id %> --enterprise acme --cabinet api-gateway --environment prod --cluster prod-cluster-1 --to-script' },
];
CabinetClusterAttach.flags = {
    enterprise: core_1.Flags.string({ char: 'e', description: 'The name of the enterprise in which the cabinet resides. NOTE: You can leave this blank if there is only one.' }),
    cabinet: core_1.Flags.string({ char: 'b', required: false, description: 'Name of the cabinet to attach.' }),
    environment: core_1.Flags.string({ char: 'n', required: false, description: 'Name of the environment the cabinet belongs to.' }),
    cluster: core_1.Flags.string({ char: 'c', required: false, description: 'Name of the cluster to attach the cabinet to.' }),
    force: core_1.Flags.boolean({ required: false, description: "Automatically attaches the cluster to the cabinet's environment first if it isn't already attached there." }),
    silent: core_1.Flags.boolean({ exclusive: ["echo", "to-script"], description: 'Non-Interactive mode; executes without any user interaction and fails on any missing or invalid arguments.' }),
    echo: core_1.Flags.boolean({ exclusive: ["to-script", "silent"], description: 'Echo interaction mode; renders the equivalent non-interactive cli command for future use before final execution.' }),
    "to-script": core_1.Flags.boolean({ exclusive: ["echo", "silent"], description: 'Toscript interaction mode; renders the equivalent non-interactive cli command WITHOUT any execution.' }),
    "take-defaults": core_1.Flags.boolean({ exclusive: ["silent"], description: "Prevents prompting for confirmation on parameters that were passed in or were automatically set to default values (Irrelevant in --silent mode)." })
};
CabinetClusterAttach.args = {};
//# sourceMappingURL=attach.js.map