"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PROMPT_ME_DESIGNATOR = void 0;
const tslib_1 = require("tslib");
require("reflect-metadata");
const core_1 = require("@oclif/core");
const dom = require("@codiac.io/codiac-domain");
const command_base_exec_1 = require("../../command-base-exec");
const output_format_enum_1 = require("../../cli-entities/output-format-enum");
const config_ui_utils_1 = require("../../uilogic/config-ui-utils");
const config_file_target_1 = require("../../uilogic/config-file-target");
const type_safety_utils_1 = require("../../uilogic/type-safety-utils");
const codiac_utils_1 = require("../../codiac-utils");
/** The value provided as input that indicates
 * a user's desire to be prompted with a list from which choose the value(s),
 * instead of entering them manually or taking a default. */
exports.PROMPT_ME_DESIGNATOR = "?";
class ConfigView extends command_base_exec_1.CommandBaseExec {
    // --------------------------------------------------------------------
    // Lazy-loaded properties
    get configUtils() {
        if (this._configUtils_backer === undefined) {
            this._configUtils_backer = this.ioc.get(config_ui_utils_1.ConfigUiUtils);
        }
        return this._configUtils_backer;
    }
    // --------------------------------------------------------------------
    bootstrap() {
        super.bootstrap();
        this.ioc.bind(config_ui_utils_1.ConfigUiUtils).toSelf();
    }
    captureArgs() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { flags } = yield this.parse(ConfigView);
            let partial = {};
            let explicit = {};
            if (flags.enterprise) {
                partial.enterprise = flags.enterprise;
            }
            if (flags.asset) {
                partial.assetName = flags.asset.trim();
                explicit.assetName = partial.assetName;
            }
            if (flags.cabinet) {
                partial.cabinetName = flags.cabinet;
                explicit.cabinetName = flags.cabinet;
            }
            // configName: --type takes precedence over --file; encode the type as "[type]" for downstream
            if (flags.type) {
                partial.configName = config_file_target_1.ConfigFileTarget.encode(flags.type);
                explicit.configName = partial.configName;
            }
            else if (flags.file) {
                partial.configName = flags.file;
                explicit.configName = flags.file;
            }
            if (flags.output) {
                const resolvedOutput = type_safety_utils_1.TypeSafetyUtils.toEnum(output_format_enum_1.OutputFormatEnum, flags.output);
                if (resolvedOutput == undefined)
                    throw new Error(`Unrecognised --output value: "${flags.output}". Valid options are: ${Object.values(output_format_enum_1.OutputFormatEnum).join(', ')}.`);
                partial.outputFormat = resolvedOutput;
                explicit.outputFormat = resolvedOutput;
            }
            return [partial, false, explicit];
        });
    }
    buildCandidate_silently(partial, rootMap, _explicit) {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            if (!partial.cabinetName)
                throw new Error("Cabinet name (--cabinet or -c) is required in silent mode.");
            if (!partial.assetName)
                throw new Error("Asset name (--asset or -a) is required in silent mode.");
            return {
                enterprise: partial.enterprise,
                assetName: partial.assetName,
                cabinetName: partial.cabinetName,
                configName: (_a = partial.configName) !== null && _a !== void 0 ? _a : 'app-config.json',
                outputFormat: (_b = partial.outputFormat) !== null && _b !== void 0 ? _b : output_format_enum_1.OutputFormatEnum.auto,
                thisMachine: partial.thisMachine,
            };
        });
    }
    buildCandidate_interactively(partial, rootMap, takeDefaults, explicit) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const enterprise = rootMap.enterprises.find(e => e.name === partial.enterprise);
            if (!enterprise)
                throw new Error(`Enterprise "${partial.enterprise}" not found.`);
            const isInfrxEnterprise = codiac_utils_1.CodiacUtils.isInfrxEnterprise(partial.enterprise);
            // Determine which asset
            let assetName;
            let assetType;
            if (partial.assetName === exports.PROMPT_ME_DESIGNATOR || partial.assetName) {
                const [resolvedName, , resolvedType] = yield this.configUtils.promptForAsset(enterprise.assets, partial.assetName);
                assetName = resolvedName;
                assetType = resolvedType;
            }
            else {
                const requestedAssets = yield this.establishAssetContext(enterprise, false);
                assetName = requestedAssets[0];
            }
            // Determine config type and file
            // partial.configName is either a filename or "[type]" (set in captureArgs); derive inputs for promptForTypeAndFile
            let selectedFile = config_file_target_1.ConfigFileTarget.toFile(partial.configName);
            let configType = config_file_target_1.ConfigFileTarget.decode(partial.configName);
            const [resolvedConfigType, resolvedFile] = yield this.configUtils.promptForTypeAndFile(partial.enterprise, assetName, assetType, configType, selectedFile, undefined, false, false, undefined, isInfrxEnterprise);
            const configName = config_file_target_1.ConfigFileTarget.encodeOrFile(resolvedConfigType, resolvedFile);
            // Determine cabinet
            const [cab] = yield this.configUtils.promptForCabinet(partial.enterprise, rootMap, partial.cabinetName, takeDefaults, undefined, explicit === null || explicit === void 0 ? void 0 : explicit.cabinetName);
            const outputFormat = (_a = partial.outputFormat) !== null && _a !== void 0 ? _a : output_format_enum_1.OutputFormatEnum.auto;
            return {
                enterprise: partial.enterprise,
                assetName,
                cabinetName: cab.name,
                configName,
                outputFormat,
                thisMachine: cab.thisMachine,
            };
        });
    }
    buildCommandString(candidate, cmd) {
        cmd.push("-e", candidate.enterprise);
        cmd.push("-a", candidate.assetName);
        cmd.push("-c", candidate.cabinetName);
        cmd.push("-f", candidate.configName);
        cmd.push("-o", candidate.outputFormat);
        cmd.push("--silent");
        return cmd;
    }
    executeTask(candidate) {
        var _a, _b, _c;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const result = yield this.genRelayClient.Call.GetRenderedCabinetConfig({
                configName: candidate.configName,
                enterprise: candidate.enterprise,
                cabinetName: candidate.cabinetName,
                assetName: candidate.assetName,
                outputFormat: candidate.outputFormat
            }, { thisMachine: candidate.thisMachine });
            if (result.success && result.output !== undefined) {
                this._ui.userMessage(`${this._styler.hilite(candidate.configName)} for ${this._styler.hilite(candidate.enterprise)}/${this._styler.hilite(candidate.assetName)} in cabinet: [${this._styler.hilite(candidate.cabinetName)}]`);
                this._ui.dataOutput(result.output);
            }
            else {
                this._ui.userMessage((_c = (_a = result.message) !== null && _a !== void 0 ? _a : (_b = result.error) === null || _b === void 0 ? void 0 : _b.message) !== null && _c !== void 0 ? _c : "Failed rendering");
            }
        });
    }
}
exports.default = ConfigView;
ConfigView.description = 'Retrieves a pre-deploy preview of the ultimate configuration file contents for the given cabinet (with all inline variables and source references resolved).';
ConfigView.aliases = ['config:preview', 'cfg:preview'];
ConfigView.flags = {
    help: core_1.Flags.help({ char: 'h' }),
    enterprise: core_1.Flags.string({ char: 'e', required: false, description: 'The name of the enterprise that contains the asset (defaults to the current enterprise context).' }),
    asset: core_1.Flags.string({ char: 'a', required: false, description: `Name of the asset to view configs for (use ${exports.PROMPT_ME_DESIGNATOR} to be prompted).` }),
    cabinet: core_1.Flags.string({ char: 'c', description: 'The name of the cabinet to assemble the configuration for.' }),
    file: core_1.Flags.string({ char: 'f', required: false, description: 'The relative pathname of the config file to view, relative to the root of the codiac project (defaults to app-config.json).' }),
    type: core_1.Flags.string({ char: 't', exclusive: ["file"], options: Object.keys(dom.SpecialConfigTypesEnum), description: 'The type of settings to view (env: OS environment variables, footprint: container footprint specs, helm: helm chart settings, label: container meta labels, annotation: container platform key-value pairs).' }),
    output: core_1.Flags.string({ char: 'o', required: false, options: [output_format_enum_1.OutputFormatEnum.pretty, output_format_enum_1.OutputFormatEnum.json, output_format_enum_1.OutputFormatEnum.yaml, output_format_enum_1.OutputFormatEnum.auto], description: "Format in which to render the config document (defaults to auto)." }),
    prompt: core_1.Flags.boolean({ char: 'p', default: false, description: 'Forces a prompt to select from the existing settings.' }),
    silent: core_1.Flags.boolean({ exclusive: ["echo", "to-script"], description: 'Executes without any user interaction; fails on missing or invalid arguments.' }),
    echo: core_1.Flags.boolean({ exclusive: ["to-script", "silent"], description: 'Renders the equivalent non-interactive command for future use before executing.' }),
    "to-script": core_1.Flags.boolean({ exclusive: ["echo", "silent"], description: 'Renders the equivalent non-interactive command without executing it.' }),
};
ConfigView.args = {
    setting: core_1.Args.string({ description: '(optional) Name of a specific setting to view; omit to show all.', required: false })
};
ConfigView.examples = [
    { description: "View config for the current asset interactively.", command: "<%= config.bin %> <%= command.id %>" },
    { description: "View a specific cabinet's config in pretty format.", command: "<%= config.bin %> <%= command.id %> -c dev2 -f settings.json -o pretty" },
    { description: "View a specific non-file config type.", command: "<%= config.bin %> <%= command.id %> -c dev2 -a myapi -t footprint" },
    { description: "Non-interactive (scripted) invocation.", command: "<%= config.bin %> <%= command.id %> -e myEnterprise -a myApi -c dev --silent" },
    { description: "Renders the equivalent silent command without executing.", command: "<%= config.bin %> <%= command.id %> -e myEnterprise -a myApi -c dev --to-script" },
];
//# sourceMappingURL=view.js.map