"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetProbeUiLogic = void 0;
const tslib_1 = require("tslib");
const path = require("path");
const core_1 = require("@oclif/core");
const YAML = require("yaml");
const _ = require("lodash");
const contracts_1 = require("../../../apis/codiac-api/contracts");
const command_base_exec_1 = require("../../../command-base-exec");
const config_ui_utils_1 = require("../../../uilogic/config-ui-utils");
const prettify_1 = require("../../../prettify");
const output_format_enum_1 = require("../../../cli-entities/output-format-enum");
const contracts_2 = require("../../../relay/contracts");
const type_safety_utils_1 = require("../../../uilogic/type-safety-utils");
class AssetProbeUiLogic {
    /** Determines an overall true/false result for the given input
     * over the given collection of individual boolean checks.  */
    static checkAll(input, filters) {
        let ultimate = true;
        for (let filter of filters) {
            ultimate = ultimate && filter(input);
            if (!ultimate)
                break;
        }
        return ultimate;
    }
    /** COnverts to the name of the kvp store technology WITHOUT the cloud provider prefix.
     * eg: `azKeyVault` converts to `"Key Vault"`
     */
    static friendlyNameFor(type) {
        switch (type) {
            case contracts_2.KvpStoreTypesEnum.awsKeyVault: return "SecretStore";
            case contracts_2.KvpStoreTypesEnum.azKeyVault: return "KeyVault";
            case contracts_2.KvpStoreTypesEnum.azBlob: return "BlobStorage";
            default: return type.toString();
        }
    }
    static actionTypeFor(entity) {
        var _a;
        let actionType;
        if (typeof entity.action == "string") {
            return contracts_1.ProbeActionTypesEnum.exec;
        }
        else {
            return (_a = entity.action.actionType) !== null && _a !== void 0 ? _a : contracts_1.ProbeActionTypesEnum.exec;
        }
    }
    static actionAbbrvFor(entity) {
        var _a, _b, _c, _d;
        if (typeof entity.action == "string") {
            return entity.action; // exec action
        }
        else {
            switch (entity.action.actionType) {
                case contracts_1.ProbeActionTypesEnum.exec: return (_b = (_a = entity.action.command) === null || _a === void 0 ? void 0 : _a.join(" ")) !== null && _b !== void 0 ? _b : "*missing command*";
                case contracts_1.ProbeActionTypesEnum.http: {
                    let axn = entity.action;
                    return ((_c = axn.scheme) !== null && _c !== void 0 ? _c : "http").concat("://", path.posix.join((_d = axn.host) !== null && _d !== void 0 ? _d : "<podIP>" + (axn.port ? ":" + axn.port : ""), axn.path));
                }
                case contracts_1.ProbeActionTypesEnum.socket: return "";
                case contracts_1.ProbeActionTypesEnum.grpc: return "";
            }
        }
    }
    static displayNameFor(entity, styler, hilite = true) {
        let abbrv = this.actionAbbrvFor(entity);
        let display = entity.asset.concat(": ", (hilite ? styler.hilite(entity.type.toString()) : styler.bold(entity.type.toString())), entity.periodSeconds ? styler.dim(" @ " + entity.periodSeconds + "s") : "", styler.dim(" -> "), this.actionTypeFor(entity), (abbrv) ? " (" + abbrv + ")" : "");
        if (entity.disabled == true) {
            display = styler.dim("[DISABLED] ".concat(display));
        }
        return display;
    }
}
exports.AssetProbeUiLogic = AssetProbeUiLogic;
class AssetProbeList extends command_base_exec_1.CommandBaseExec {
    captureArgs() {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { args, flags } = yield this.parse(AssetProbeList);
            let partial = {};
            if (flags.enterprise)
                partial.enterprise = flags.enterprise;
            if (flags.asset)
                partial.asset = flags.asset;
            // if (flags.type) partial.type = (<any>ProbeUsageTypesEnum)(flags.type);  // TODO: Add this to the criteria
            if (flags.action)
                partial.actionType = type_safety_utils_1.TypeSafetyUtils.toEnum(contracts_1.ProbeActionTypesEnum, flags.action);
            if (flags.output)
                partial.outputFormat = type_safety_utils_1.TypeSafetyUtils.toEnum(output_format_enum_1.OutputFormatEnum, flags.output);
            // ---------------------------------------------------------------
            // 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];
        });
    }
    buildCandidate_silently(partial, rootMap) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let candidate = {
                enterprise: partial.enterprise,
                outputFormat: (_a = partial.outputFormat) !== null && _a !== void 0 ? _a : output_format_enum_1.OutputFormatEnum.auto
            };
            if (partial.asset)
                candidate.asset = partial.asset;
            // if (partial.type) candidate.type = partial.type;
            if (partial.actionType)
                candidate.actionType = partial.actionType;
            return candidate;
        });
    }
    buildCandidate_interactively(partial, rootMap, takeDefaults) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            // TODO: Add interactive prompts for provider and type 
            return this.buildCandidate_silently(partial, rootMap);
        });
    }
    buildCommandString(candidate, cmd) {
        if (candidate.enterprise)
            cmd.push("--enterprise", candidate.enterprise);
        if (candidate.asset)
            cmd.push("--asset", candidate.asset);
        // if (candidate.type) cmd.push("--type", candidate.type.toString();
        if (candidate.actionType)
            cmd.push("--action", candidate.actionType);
        if (candidate.outputFormat)
            cmd.push("-o", candidate.outputFormat);
        // TODO: Capture takeDefaults
        cmd.push("--silent");
        return cmd;
    }
    executeTask(candidate) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            // Commented out bc the relay endpoint requires provider, and we want it as an optional filter
            // --------------------------------------------------------------------------------------------------------------------------------
            // let req: GetSecretStoresRequest = {
            //   provider: candidate.provider,
            //   spec: candidate
            // };
            // 
            // let output: string;
            // let listRes = await this.genRelayClient.Call.GetSecretStores({ provider: candidate.provider, spec: req })
            // if (listRes.error) throw listRes.error;
            // 
            // output = this.renderAs(listRes.output ?? [], candidate.outputFormat, x => SecretStoreUiLogic.displayNameFor(x, this._styler));
            // --------------------------------------------------------------------------------------------------------------------------------
            let req = Object.assign({}, _.omit(candidate, "outputFormat"));
            let list = yield this._codiacApi.Probe.readMany(req);
            // TODO: Render as a tree with assets as parent branch
            let output = this.renderAs(list, candidate.outputFormat, entity => AssetProbeUiLogic.displayNameFor(entity, this._styler));
            console.log(output);
        });
    }
    /** TODO: This method is generic.  Promote it to a shared utility lib. */
    renderAs(list, format, textFormatter) {
        let output = "";
        switch (format) {
            case output_format_enum_1.OutputFormatEnum.json:
                output = JSON.stringify(list, undefined, 2);
                break;
            case output_format_enum_1.OutputFormatEnum.yaml:
                output = YAML.stringify(list, { indent: 2 });
                break;
            case output_format_enum_1.OutputFormatEnum.pretty:
            case output_format_enum_1.OutputFormatEnum.auto:
            default:
                if (list.length > 0) {
                    if (textFormatter) {
                        output = list.map(x => textFormatter(x)).join("\n");
                    }
                    else {
                        output = (0, prettify_1.prettify)(list);
                    }
                }
                else {
                    output = "None found.";
                }
                break;
        }
        return output;
    }
}
exports.default = AssetProbeList;
// static aliases = ["probe:list"]
AssetProbeList.description = 'Retrieves the list of existing secret stores captured for a given enterprise.';
AssetProbeList.examples = [
    '<%= config.bin %> <%= command.id %>',
];
/** The values that this command supports for the "type" flag.  */
AssetProbeList.STORE_TYPE_OPTIONS = ["aws-secrets", "az-key-vault"];
AssetProbeList.flags = {
    enterprise: core_1.Flags.string({ char: 'e', description: '(optional if there is only one) The enterprise in which the probes are defined.' }),
    asset: core_1.Flags.string({ char: 'a', required: false, description: 'The asset that owns the probe.' }),
    type: core_1.Flags.string({ char: 't', options: Object.values(contracts_1.ProbeUsageTypesEnum), required: false, description: "Filter on the purpose/lifecycle role of the probe." }),
    action: core_1.Flags.string({ char: 'x', options: Object.values(contracts_1.ProbeActionTypesEnum), required: false, description: "Filter on the type of action used by the probe." }),
    // output list, table, json, yaml (wd love to have jmespath and/or a template and/or a projection)
    output: core_1.Flags.string({ char: 'o', default: output_format_enum_1.OutputFormatEnum.auto, 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.auto] }),
    // 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." })
};
AssetProbeList.args = {};
//# sourceMappingURL=list.js.map