"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const _ = require("lodash");
const YAML = require("yaml");
const command_base_exec_tenant_1 = require("../../../command-base-exec-tenant");
const output_format_enum_1 = require("../../../cli-entities/output-format-enum");
const config_ui_utils_1 = require("../../../uilogic/config-ui-utils");
const prettify_1 = require("../../../prettify");
const type_safety_utils_1 = require("../../../uilogic/type-safety-utils");
const clusterProjxn = { pathsIncluded: ["id", "name", "provider", "locationName", "instance", "modified", "modifiedBy"], pathsExcluded: [] };
class NocClusterJournal extends command_base_exec_tenant_1.CommandBaseExecTenant {
    constructor() {
        super(...arguments);
        this.adminOnly = false;
    }
    captureArgs() {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { args, flags } = yield this.parse(NocClusterJournal);
            let partial = {};
            if (flags.output)
                partial.outputFormat = type_safety_utils_1.TypeSafetyUtils.toEnum(output_format_enum_1.OutputFormatEnum, flags.output);
            if (args.cluster)
                partial.cluster = args.cluster;
            // ---------------------------------------------------------------
            // TODO: move everything from here down into the base class
            // ---------------------------------------------------------------
            const interactionMode = (this.pipedInput) ? config_ui_utils_1.InteractionModes.silent : (_b = (_a = undefined !== null && undefined !== void 0 ? undefined : (flags.echo ? config_ui_utils_1.InteractionModes.echo : undefined)) !== null && _a !== void 0 ? _a : (flags["to-script"] ? config_ui_utils_1.InteractionModes.toscript : undefined)) !== null && _b !== void 0 ? _b : (flags.silent ? config_ui_utils_1.InteractionModes.silent : undefined);
            const takeDefaults = flags['take-defaults'];
            return [partial, interactionMode, takeDefaults];
        });
    }
    // /** Throws on invalid */
    // private validate(partial: Partial<IAuthRoleDef>): void {
    //   if (partial.name == undefined || _.isEmpty(partial.name)) throw new Error("Missing name");
    //   let rxName = /^[a-zA-Z][a-zA-Z0-9-]{2,50}$/;
    //   if (!rxName.test(partial.name)) throw new Error("Invalid name: must be 3- to 50-character string of alphanumerics and hyphens, starting with a letter.");
    // }
    buildCandidate_silently(partial) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (partial.cluster == undefined || _.isEmpty(partial.cluster)) {
                throw new Error("You must specify a cluster in silent mode.");
            }
            let clusters = yield this.loadClusters();
            if (clusters.find(c => c.name == partial.cluster) == undefined) {
                throw new Error("Cluster not found.");
            }
            let candidate = {
                cluster: partial.cluster,
                outputFormat: (_a = partial.outputFormat) !== null && _a !== void 0 ? _a : output_format_enum_1.OutputFormatEnum.pretty
            };
            return candidate;
        });
    }
    buildCandidate_interactively(partial, takeDefaults) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let clusters = yield this.loadClusters();
            let selected;
            if (clusters.length == 1 && (takeDefaults == true)) {
                selected = clusters[0];
            }
            else {
                selected = yield this.promptForCluster(clusters, partial.cluster);
            }
            partial.cluster = selected.name;
            // Prompt for output format
            return yield this.buildCandidate_silently(partial);
        });
    }
    buildCommandString(candidate, cmd) {
        cmd.push("--output", candidate.outputFormat);
        cmd.push("--silent");
        cmd.push(candidate.cluster);
        return cmd;
    }
    executeTask(candidate) {
        var _a, _b, _c, _d;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if ([output_format_enum_1.OutputFormatEnum.json, output_format_enum_1.OutputFormatEnum.yaml].includes(candidate.outputFormat) === false)
                this._ui.startSpinner("Retrieving");
            let crit = { resourceId: candidate.cluster };
            let result = yield this._codiacApi.SetupJournal.tryReadMany(crit);
            let doneMsg = (result.error) ? "Error" : "Found ".concat(((_b = (_a = result.output) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0).toString());
            if ([output_format_enum_1.OutputFormatEnum.json, output_format_enum_1.OutputFormatEnum.yaml].includes(candidate.outputFormat) === false)
                this._ui.stopSpinner(doneMsg);
            if (result.error)
                throw result.error;
            let journal = (result.output && (((_d = (_c = result.output) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) > 0)) ? result.output[0] : undefined;
            if (journal == undefined) {
                this._ui.userMessage("That cluster has no setup journal.");
            }
            else {
                // RENDER
                let output = "";
                switch (candidate.outputFormat) {
                    case output_format_enum_1.OutputFormatEnum.yaml:
                        output = YAML.stringify(journal, { indent: 2 });
                        this._ui.userMessage(output);
                        break;
                    case output_format_enum_1.OutputFormatEnum.json:
                        output = JSON.stringify(journal, undefined, 2);
                        this._ui.userMessage(output);
                        break;
                    case output_format_enum_1.OutputFormatEnum.pretty:
                    default:
                        output = (0, prettify_1.prettify)(journal);
                        this._ui.userMessage(output);
                        break;
                }
            }
            return;
        });
    }
    loadClusters() {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                let readResult = yield this._codiacApi.ClusterDef.tryReadMany({ all: true }, { projection: clusterProjxn });
                let clusterDefs = (_b = (_a = readResult.output) === null || _a === void 0 ? void 0 : _a.map(c => c)) !== null && _b !== void 0 ? _b : [];
                clusterDefs = _.orderBy(clusterDefs, c => c.name);
                return clusterDefs;
            }
            catch (err) {
                throw err;
            }
        });
    }
    /** Renders a user-friendly cluster description. */
    describe(cluster) {
        return `${cluster.name} ${this._styler.dim("(" + cluster.provider + (cluster.locationName ? ", " + cluster.locationName : "") + ")")}`;
    }
    /** Returns the name of the selected cluster.
    */
    promptForCluster(clusters, defaultValue) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let output;
            let keep = false;
            if (defaultValue && clusters.find(c => c.name === defaultValue)) {
                keep = yield this._ui.promptConfirm("clusterNameConfirm", `Target Cluster: [${this._styler.hilite(defaultValue)}]`, true);
            }
            if (keep === true) {
                output = clusters.find(c => c.name === defaultValue);
            }
            else {
                let choices = clusters
                    .map(c => { return { name: this.describe(c), value: c.name }; });
                let selectedName = (yield this._ui.promptSelect("clusterName", "Select the target cluster:", choices));
                output = clusters.find(c => c.name === selectedName);
            }
            return output;
        });
    }
}
exports.default = NocClusterJournal;
NocClusterJournal.description = 'Shows the setup journal for the given cluster.  The journal outlines the individual components that were created in the CSP subscription (Cloud Service Provider) comprising the cluster.';
NocClusterJournal.aliases = ["cluster:journal"];
NocClusterJournal.examples = [
    '<%= config.bin %> <%= command.id %>',
    '<%= config.bin %> <%= command.id %> --echo',
    '<%= config.bin %> <%= command.id %> dev-west-aws-02',
    '<%= config.bin %> <%= command.id %> -o yaml dev-west-aws-02',
    '<%= config.bin %> <%= command.id %> -o yaml --silent dev-west-aws-02',
    '<%= config.bin %> <%= command.id %> -o yaml --silent dev-west-aws-02 > myfiles/journal.yaml'
];
NocClusterJournal.flags = {
    output: core_1.Flags.string({ char: 'o', default: output_format_enum_1.OutputFormatEnum.pretty, description: "format in which to render the data.", options: [output_format_enum_1.OutputFormatEnum.json, output_format_enum_1.OutputFormatEnum.yaml, output_format_enum_1.OutputFormatEnum.pretty] }),
    // TODO: Move these into the base class
    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: "Setting this to true prevents prompting for confirmation on parameters that were passed in or were automatically set to default values (Irrelevant in --silent mode).  This behavior does NOT apply to scenarios that the command needs to override invalid user input; such cases will always prompt for confirmation.  eg: when no argument was provided for file or type, and only one exists, the system will render the autoselected file unless this flag is set." })
};
NocClusterJournal.args = {
    cluster: core_1.Args.string({ description: 'Name of the cluster in Codiac.  You can use `cod cluster list` to see the names of your codiac clusters.' }),
};
//# sourceMappingURL=journal.js.map