"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PROMPT_ME_DESIGNATOR = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const inquirer = require("inquirer");
const _ = require("lodash");
// import { Asset, EnterpriseCriteria, Kit, KitAccessibilityEnum } from '@codiac.io/codiac-domain';
const contracts_1 = require("../../apis/codiac-api/contracts");
const command_base_enterprise_1 = require("../../command-base-enterprise");
const prettify_1 = require("../../prettify");
/** 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 KitCreate extends command_base_enterprise_1.CommandBaseEnterprise {
    run() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                try {
                    this.bootstrap();
                    const { args, flags } = yield this.parse(KitCreate);
                    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
                    let enterpriseCode = currentEnterprise.name;
                    // 1) Get the asset record
                    let asset;
                    if (!flags.asset || flags.asset == exports.PROMPT_ME_DESIGNATOR) {
                        asset = yield this.promptForAsset(enterpriseCode);
                    }
                    else /* if (flags.asset) */ {
                        asset = yield this.promptForAsset(enterpriseCode, flags.asset);
                    }
                    // 2) Generate the kit
                    let kitRes = yield this.genRelayClient.Call.getGenerateAssetFromKit({ kitName: asset.name, targetEnterprise: asset.enterprise });
                    if (kitRes.success && kitRes.output) {
                        let candidate = kitRes.output;
                        // Loop thru the kit properties and allow the user to override.
                        let confirmed = false;
                        while (!confirmed) {
                            console.clear();
                            this._ui.userMessage(this._styler.bold("New Kit:"));
                            candidate.name = (yield this._ui.prompt("name", "Name: ", true, candidate.name));
                            candidate.library = (yield this._ui.prompt("library", "Library: ", true, candidate.library));
                            candidate.description = (yield this._ui.prompt("description", "Description: ", true, candidate.description));
                            let choices = [contracts_1.KitAccessibilityEnum.private, contracts_1.KitAccessibilityEnum.friends, contracts_1.KitAccessibilityEnum.public];
                            candidate.accessibleBy = (yield this._ui.promptSelect("accessibleBy", "AccessibleBy: ", choices, false));
                            console.clear();
                            let msg = (0, prettify_1.prettify)(candidate);
                            this._ui.userMessage(msg);
                            this._ui.userMessage(`You are about to create this kit. Continue?`);
                            confirmed = yield this._ui.promptConfirm("confirmCreate", `(hit 'N' to edit your input)`, false);
                            if (confirmed == true) {
                                yield this.createKit(candidate);
                            }
                            else {
                                this.logger.notice(`Operation cancelled. No work was done.`);
                                this._ui.userMessage(`Operation cancelled. No work was done.`);
                            }
                        }
                    }
                    else if (kitRes.error) {
                        throw kitRes.error;
                    }
                }
                catch (err) {
                    this.handleError(err);
                }
                finally {
                    yield this.closeConnections();
                    resolve();
                }
            }));
        });
    }
    promptForAsset(enterprise, assetSearch) {
        return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                // let ecrit = new EnterpriseCriteria();
                // ecrit.code = new StringFilter();
                // ecrit.code.$eq = enterprise;
                let ecrit = { code: enterprise };
                let readResult = yield this._codiacApi.Enterprise.tryReadMany(ecrit /* { code: { $eq: enterprise } }  */);
                if (!readResult.output || readResult.output.length == 0) {
                    throw new Error(`Could not find enterprise [${enterprise}].`);
                }
                else if (!readResult.output[0].assets || readResult.output[0].assets.length == 0) {
                    throw new Error(`The current enterprise [${enterprise}] has no assets defined.`);
                }
                // console.log(`${readResult.output[0].assets.length} assets found`)
                // Select from assets in the current enterprise
                let assets = readResult.output[0].assets;
                if (assetSearch && assetSearch != exports.PROMPT_ME_DESIGNATOR) {
                    assets = assets.filter(a => a.name.startsWith(assetSearch));
                }
                // console.log(`${assets.length} assets found`)
                let assSelect = yield inquirer.prompt({ type: 'list', name: 'asset', message: 'Select an Asset:', choices: assets.map(a => a.name).sort() });
                let selected = assets.find(a => a.name == assSelect.asset);
                if (!selected)
                    throw new Error(`User failed to select a valid asset to deploy.`);
                resolve(selected);
            }
            catch (err) {
                reject(err);
            }
        }));
    }
    createKit(kit) {
        return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                let result = yield this._codiacApi.Kit.tryCreate(kit);
                if (result.error)
                    throw result.error;
                let kitFqn = `${kit.library}/${kit.name}`;
                if (!result.success || !result.output)
                    throw new Error(`Failed without error creating kit [${kitFqn}]: ${result.message}.`);
                this.logger.notice(`${this._styler.colorGood("SUCCESS!")} Created new kit ${this._styler.bold(this._styler.hilite(kitFqn))}.`, result.output);
                this._ui.userMessage(`${this._styler.colorGood("SUCCESS!")} Created new kit ${this._styler.bold(this._styler.hilite(kitFqn))}.`);
                resolve();
            }
            catch (err) {
                this.logger.error(err, kit);
                resolve();
                // reject(err);
            }
        }));
    }
}
exports.default = KitCreate;
KitCreate.description = 'Creates a new kit from an existing asset.';
KitCreate.aliases = [];
KitCreate.dependsOn = ["asset", "enterprise", "name", "scope"];
KitCreate.flags = {
    help: core_1.Flags.help({ char: 'h' }),
    asset: core_1.Flags.string({ char: 'a', required: false, description: "The enterprise asset from which to create the kit." }),
    enterprise: core_1.Flags.string({ char: 'e', required: false, description: 'The name of the enterprise containing the given asset. (defaults to the current enterprise context)' }),
    name: core_1.Flags.string({ char: 'n', required: false, description: "Override for the name to give the new kit (Optional: defaults to the asset name)." }),
    scope: core_1.Flags.string({ char: 's', required: false, description: "The globally unique name for the directory in which to register the kit.  This value prefixes the kit name to ensure global uniqueness (Optional: defaults to the public shared library)." }),
    silent: core_1.Flags.boolean({ char: 'y', dependsOn: KitCreate.dependsOn, required: false, description: `(Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs. Requires: ${KitCreate.dependsOn}` })
};
KitCreate.args = {
    setting: core_1.Args.string({ description: 'The key for the config setting to add' })
};
//# sourceMappingURL=create.js.map