"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AssetEdit = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const _ = require("lodash");
const command_base_exec_1 = require("../../command-base-exec");
const config_ui_utils_1 = require("../../uilogic/config-ui-utils");
const asset_configurator_1 = require("../../uilogic/cloud-resource-configurators/asset-configurator");
const prettify_1 = require("../../prettify");
class AssetEdit extends command_base_exec_1.CommandBaseExec {
    get uiAsset() {
        if (this.uiAsset_backer == undefined) {
            this.uiAsset_backer = new asset_configurator_1.AssetConfigurator(this._ui, this._styler, this.genRelayClient, this.logger); // this.ioc.get(AssetConfigurator);
        }
        return this.uiAsset_backer;
    }
    captureArgs() {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { args, flags } = yield this.parse(AssetEdit);
            let partial = {};
            if (flags.enterprise)
                partial.enterprise = flags.enterprise;
            if (flags.name)
                partial.name = flags.name;
            if (flags.code)
                partial.code = flags.code;
            if (flags.id)
                partial.id = flags.id;
            // ---------------------------------------------------------------
            // 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, false];
        });
    }
    buildCandidate_silently(partial, rootMap) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let ent = rootMap.enterprises.find(e => e.name == partial.enterprise);
            if (!ent)
                throw new Error("Enterprise not found."); // <-- todo: move this up to the base class and pass in the enterprise object.
            if (partial.name == undefined)
                throw new Error("Missing asset name.");
            let asset = ent.assets.find(a => a.name == partial.name);
            if (!asset)
                throw new Error("Asset not found");
            // Overlay the existing record with the given property values
            partial = _.merge({}, asset, partial);
            let candidate = Object.assign({}, partial);
            return candidate;
        });
    }
    buildCandidate_interactively(partial, rootMap, takeDefaults) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let ent = rootMap.enterprises.find(e => e.name == partial.enterprise);
            if (!ent) {
                ent = yield this.rootMapUtils.promptForEnterprise(partial, rootMap);
                partial.enterprise = ent.name;
            }
            // Dont await: let this run in the background while the user is interacting.
            if (!this.uiAsset.isLoaded)
                this.uiAsset.load(ent.assets);
            let assetChanged;
            let assetType;
            [partial.name, assetChanged, assetType] = yield this.rootMapUtils.promptForAsset(ent.assets, partial.name);
            let asset = ent.assets.find(a => a.name == partial.name);
            if (!asset)
                throw new Error("Asset not found"); // <-- this will never happen - it's just for type safety
            // Overlay the existing record with the given property values
            partial = _.merge({}, asset, partial);
            let candidate;
            let confirm = false;
            do {
                // TODO: edit stuff here...
                let edited = yield this.uiAsset.editAsset(partial);
                // TODO: show diffs only from asset
                candidate = Object.assign({}, edited);
                this._ui.userMessage("Changes to ".concat(candidate.name, "... "));
                this._ui.userMessage((0, prettify_1.prettify)(candidate));
                confirm = yield this._ui.promptConfirm("confirm", "Save changes?", false);
            } while (!confirm);
            return candidate;
        });
    }
    buildCommandString(candidate, cmd) {
        cmd.push("--enterprise", candidate.enterprise);
        cmd.push("--name", candidate.name);
        // cmd.push("--id", candidate.id)
        if (candidate.code)
            cmd.push("--code");
        cmd.push("--silent");
        return cmd;
    }
    executeTask(candidate) {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let result = yield this._codiacApi.Asset.tryUpdate(candidate);
            if (result.error != undefined) {
                throw result.error;
            }
            else if (result.success == true) {
                this._ui.userMessage((_a = result.message) !== null && _a !== void 0 ? _a : "Successfully updated asset ".concat("[", candidate.name, "]"));
            }
            else {
                this._ui.userMessage((_b = result.message) !== null && _b !== void 0 ? _b : "Failed without error updating asset record for ".concat("[", candidate.name, "].  Check logs for details."));
            }
        });
    }
}
exports.AssetEdit = AssetEdit;
AssetEdit.description = 'Changes asset attributes.';
AssetEdit.args = {};
AssetEdit.flags = {
    enterprise: core_1.Flags.string({ char: 'e', required: false, description: 'The name of the enterprise in which this asset resides. (defaults to the current enterprise context).  NOTE: The enterprise assignment for an asset is immutable and cannot be modified; this flag is used only for identifying the asset.' }),
    name: core_1.Flags.string({ char: 'n', required: false, description: "The name of the asset to edit.  NOTE: The asset name is immutable and cannot be modified; this flag is used only for identifying the asset." }),
    code: core_1.Flags.string({ char: 'c', required: false, description: "The host name to assign this asset in the domain url.  eg: 'myasset' in 'myasset.your-domain.com' (Optional: defaults to the asset name)." }),
    // id: Flags.string({ required: false, description: "The system id of the enterprise asset to edit." }),
    // TODO: Move these into the base class
    silent: core_1.Flags.boolean({ exclusive: ["echo", "to-script"], dependsOn: ["name"], 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": 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." })
};
AssetEdit.examples = [
    '<%= config.bin %> <%= command.id %>',
    '<%= config.bin %> <%= command.id %> -n my-api',
    '<%= config.bin %> <%= command.id %> -e main -n my-api',
];
//# sourceMappingURL=edit.js.map