"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const YAML = require("yaml");
const command_base_enterprise_1 = require("../../command-base-enterprise");
const _ = require("lodash");
const render = require("../../uilogic/render-methods");
const render_methods_1 = require("../../uilogic/render-methods");
const enterprise_contextualizer_1 = require("../../uilogic/enterprise-contextualizer");
const type_safety_utils_1 = require("../../uilogic/type-safety-utils");
const codiac_constants_1 = require("../../codiac-constants");
class AssetList extends command_base_enterprise_1.CommandBaseEnterprise {
    run() {
        var _a, _b, _c;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.bootstrap();
            const { args, flags } = yield this.parse(AssetList);
            try {
                this._userCntx = yield this.establishTenantContext(this._userCntx);
                let rootMap = yield this.getRootMap();
                const interactionMode = this.getInteractionMode(flags.silent, flags.echo, flags['to-script']);
                let currentEnterprise = (yield this.establishEnterpriseContext(rootMap, flags.enterprise, interactionMode)).enterprise;
                _.remove(rootMap.enterprises, e => e.name != currentEnterprise.name); // trim down to match legacy conditions
                // RETRIEVE 
                // if ([OutputFormatsEnum.json, OutputFormatsEnum.yaml].includes(outputFormat) === false) this._ui.startSpinner("Retrieving");
                // let rootMapResult = await this._codiacApi.Call.getRootMap(<RootMapCriteria>{ enterprise: currentEnterprise.code });
                // let rootMap: RootMap = <RootMap><any>rootMapResult; // readmany rootmap result returns a single entity instead of a list result.
                // let envCount = 0;
                // rootMap.enterprises.forEach(e => envCount += e.environments.length);
                // if ([OutputFormatsEnum.json, OutputFormatsEnum.yaml].includes(outputFormat) === false) this._ui.stopSpinner(`found ${envCount}`);
                let outputFormat = (_a = type_safety_utils_1.TypeSafetyUtils.toEnum(render_methods_1.OutputFormatsEnum, flags.output)) !== null && _a !== void 0 ? _a : render_methods_1.OutputFormatsEnum.tree;
                // RENDER
                let output = "";
                switch (outputFormat) {
                    case render_methods_1.OutputFormatsEnum.json:
                        // let listForJson: FlatEnviro[] = this.FlattenEnviros(rootMap);
                        let listForJson = currentEnterprise.assets.map(a => this.FlattenAsset(a));
                        listForJson = _.sortBy(listForJson, e => e.enterprise, a => { var _a; return (_a = a.product) !== null && _a !== void 0 ? _a : " "; }, c => c.name);
                        output = JSON.stringify(listForJson, undefined, 2);
                        this._ui.userMessage(output);
                        break;
                    case render_methods_1.OutputFormatsEnum.yaml:
                        let listForYaml = currentEnterprise.assets.map(a => this.FlattenAsset(a));
                        listForYaml = _.sortBy(listForYaml, c => c.enterprise, a => { var _a; return (_a = a.product) !== null && _a !== void 0 ? _a : " "; }, c => c.name);
                        output = YAML.stringify(listForYaml, { indent: 2 });
                        this._ui.userMessage(output);
                        break;
                    case render_methods_1.OutputFormatsEnum.text:
                        let flatList = currentEnterprise.assets.map(a => this.FlattenAsset(a));
                        flatList = _.sortBy(flatList, c => c.enterprise, a => { var _a; return (_a = a.product) !== null && _a !== void 0 ? _a : " "; }, c => c.name);
                        let listForText = this.buildAssetListForText(flatList);
                        output = render.renderStringList(listForText);
                        this._ui.userMessage(output);
                        break;
                    // TODO:
                    // case OutputFormatsEnum.table:
                    // case OutputFormatsEnum.tsv:
                    //   break;
                    case render_methods_1.OutputFormatsEnum.tree:
                    default:
                        let tree = this.buildAssetTree((_c = (_b = currentEnterprise.assets) === null || _b === void 0 ? void 0 : _b.map(a => this.FlattenAsset(a))) !== null && _c !== void 0 ? _c : []);
                        let out = render.renderStringTree(tree); //, this._ui.userMessage);
                        this._ui.userMessage(out);
                        break;
                }
                // if ([OutputFormatsEnum.tree].includes(outputFormat)) {
                //   let cabTree = this.buildCabinetTree(rootMap);
                //   let out = this.renderStringTree(cabTree); //, this._ui.userMessage);
                //   this._ui.userMessage(out);
                // } else {
                //   let flatList: FlatCabinet[] = this.FlattenCabinets(rootMap);
                //   flatList = _.sortBy(flatList, c => c.enterprise, c => c.env, c => c.name)
                //   this.renderCabinets(flatList, outputFormat);
                // }
                return;
            }
            catch (err) {
                throw err;
            }
            finally {
                yield this.closeConnections();
            }
        });
    }
    buildAssetListForText(flatList) {
        try {
            let listForText = flatList.map(asset => {
                let output = this._styler.hilite(asset.name);
                // output = output.concat
                if (asset.product !== undefined) {
                    output = asset.product.concat("/", output); // product prefix
                }
                output = asset.enterprise.concat("/", output); // enterprise prefix
                if (type_safety_utils_1.TypeSafetyUtils.toBoolean(asset.hasIngress)) {
                    if (type_safety_utils_1.TypeSafetyUtils.toBoolean(asset.ingressInternal)) {
                        output = output.concat(" ", codiac_constants_1.CliConstants.UTF8_FISHEYE);
                    }
                    else {
                        output = output.concat(" ", codiac_constants_1.CliConstants.UTF8_CLOUD);
                    }
                }
                let details = this.renderAssetDetails(asset);
                output = output.concat(this._styler.dim(` (${details})`));
                return output;
            });
            return listForText;
        }
        catch (err) {
            throw err;
        }
    }
    renderAssetDetails(asset) {
        let details = `port: ${asset.port}`;
        if (asset.hasIngress) {
            details = details.concat(", HasIngress");
        }
        else {
            details = details.concat(", no ingress");
        }
        if (asset.routedWithoutName === true) {
            details = details.concat(", RoutedWithoutName");
        }
        details = details.concat(`, from ${asset.registry}`);
        return details;
    }
    buildAssetTree(assets) {
        let tree = [];
        let sorted = _.sortBy(assets, a => a.enterprise, a => a.product, a => a.name);
        let byProduct = _.groupBy(assets, a => a.product);
        let entBranch;
        for (let product of Object.keys(byProduct).sort()) {
            let prodAssets = byProduct[product];
            let prodBranch = { text: product };
            for (let asset of _.sortBy(prodAssets, a => a.name)) {
                let text = this._styler.hilite(asset.name);
                if (type_safety_utils_1.TypeSafetyUtils.toBoolean(asset.hasIngress)) {
                    if (type_safety_utils_1.TypeSafetyUtils.toBoolean(asset.ingressInternal)) {
                        text = text.concat(" ", codiac_constants_1.CliConstants.UTF8_FISHEYE);
                    }
                    else {
                        text = text.concat(" ", codiac_constants_1.CliConstants.UTF8_CLOUD);
                    }
                }
                let details = this.renderAssetDetails(asset);
                text = text.concat(this._styler.dim(` (${details})`));
                let assetBranch = { text: text };
                if (prodBranch.children === undefined)
                    prodBranch.children = [];
                prodBranch.children.push(assetBranch);
                if (entBranch === undefined) {
                    entBranch = { text: `Enterprise: ${asset.enterprise}` };
                }
            }
            if (entBranch !== undefined) {
                if (entBranch.children === undefined)
                    entBranch.children = [];
                if (product === "undefined") { // Because: loose assets (not in a product) need to go directly under the enterprise.
                    if (prodBranch.children) {
                        entBranch.children.unshift(...prodBranch.children);
                    }
                }
                else {
                    entBranch.children.push(prodBranch);
                }
            }
        }
        if (entBranch !== undefined) {
            tree.push(entBranch);
        }
        return tree;
    }
    FlattenAsset(a) {
        let flattened = {
            name: a.name,
            code: a.code,
            enterprise: a.enterprise,
            hasIngress: a.hasIngress,
            port: enterprise_contextualizer_1.EnterpriseContextualizer.renderAsCsv(a.port),
            product: a.product,
            type: a.type,
            routedWithoutName: a.routedWithoutName,
            image: a.image.name,
            registry: a.image.registry.code,
            registryProvider: a.image.registry.provider
        };
        if (a.ingressInternal)
            flattened.ingressInternal = a.ingressInternal;
        if (a.allowHttp)
            flattened.allowHttp = a.allowHttp;
        if (a.disableHttps)
            flattened.disableHttps = a.disableHttps;
        return flattened;
    }
}
exports.default = AssetList;
AssetList.description = 'Shows the list of assets in a given enterprise.';
AssetList.flags = {
    enterprise: core_1.Flags.string({ char: 'e', required: false, description: 'The name of the enterprise containing the assets being viewed (required if there are more than one).' }),
    output: core_1.Flags.string({ char: 'o', default: render_methods_1.OutputFormatsEnum.tree, description: "format in which to render the data.", options: [render_methods_1.OutputFormatsEnum.json, render_methods_1.OutputFormatsEnum.yaml, render_methods_1.OutputFormatsEnum.tree, render_methods_1.OutputFormatsEnum.text] }),
    help: core_1.Flags.help({ char: 'h', description: 'Displays the help document for this command.' })
};
AssetList.args = {};
//# sourceMappingURL=list.js.map