"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 _ = require("lodash");
const command_base_exec_1 = require("../../../command-base-exec");
/** 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 AssetVolumeDelete extends command_base_exec_1.CommandBaseExec {
    captureArgs() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { flags } = yield this.parse(AssetVolumeDelete);
            let partial = {};
            if (flags.enterprise)
                partial.enterprise = flags.enterprise;
            return [partial, false];
        });
    }
    buildCandidate_silently(partial, rootMap) {
        var _a, _b, _c;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { flags } = yield this.parse(AssetVolumeDelete);
            if (!flags.name)
                throw new Error(`Volume mount name (--name / -n) is required in silent mode.`);
            const ent = rootMap.enterprises.find(e => e.name === partial.enterprise);
            if (!ent)
                throw new Error(`Enterprise "${partial.enterprise}" not found.`);
            // const aCntx = await this.establishAssetContext(ent, true);
            // const asset = ent.assets.find(a => a.name === aCntx[0]);
            let [assetName] = yield this.promptForAsset(ent.assets, (_a = partial.asset) === null || _a === void 0 ? void 0 : _a.name);
            let asset = ent.assets.find(a => a.name == assetName);
            if (!asset)
                throw new Error(`Asset "${(_c = (_b = partial.asset) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : ""}" not found.`);
            if (!asset.reservedFolders || asset.reservedFolders.length === 0) {
                this._ui.userMessage(`Asset [${asset.name}] in enterprise [${partial.enterprise}] has no volume mounts defined.`);
                return undefined;
            }
            const folderRes = asset.reservedFolders.find(f => f.name === flags.name);
            if (!folderRes)
                throw new Error(`No volume mount named [${flags.name}] is declared in asset [${asset.name}] in enterprise [${asset.enterprise}].`);
            return { enterprise: partial.enterprise, asset, folderRes };
        });
    }
    buildCandidate_interactively(partial, rootMap, takeDefaults) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const ent = rootMap.enterprises.find(e => e.name === partial.enterprise);
            if (!ent)
                throw new Error(`Enterprise "${partial.enterprise}" not found.`);
            const aCntx = yield this.establishAssetContext(ent, true);
            const asset = ent.assets.find(a => a.name === aCntx[0]);
            if (!asset)
                throw new Error(`Asset "${aCntx[0]}" not found.`);
            if (!asset.reservedFolders || asset.reservedFolders.length === 0) {
                this._ui.userMessage(`Asset [${asset.name}] in enterprise [${partial.enterprise}] has no volume mounts defined.`);
                this._ui.userMessage(`No work was done.`);
                return undefined;
            }
            let folderRes;
            let confirmed = false;
            while (!confirmed || !folderRes) {
                const choices = asset.reservedFolders.map(f => ({ name: `${f.name} (${f.path})`, value: f.name }));
                const selected = (yield this._ui.promptSelect("mountName", "Choose the volume mount to delete: ", choices, false));
                folderRes = asset.reservedFolders.find(f => f.name === selected);
                confirmed = yield this._ui.promptConfirm("confirm", `Delete Volume Mount [${this._styler.bold(folderRes.name)} (${folderRes.path})] from Asset [${asset.name}]?`, false);
            }
            return { enterprise: partial.enterprise, asset, folderRes };
        });
    }
    buildCommandString(candidate, cmd) {
        cmd.push("-e", candidate.enterprise);
        cmd.push("-n", candidate.folderRes.name);
        cmd.push("--silent");
        return cmd;
    }
    executeTask(candidate) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            const { asset, folderRes } = candidate;
            if (!asset.reservedFolders || asset.reservedFolders.length === 0)
                return;
            _.remove(asset.reservedFolders, f => f.name === folderRes.name);
            if (asset.reservedFolders.length > 0) {
                asset.reservedFolders = _.sortBy(asset.reservedFolders, f => f.path);
            }
            else {
                delete asset.reservedFolders;
            }
            this.logger.trace("Asset update", asset);
            const result = yield this._codiacApi.Asset.tryUpdate(asset);
            if (result.success) {
                this.logger.notice(`Successfully deleted volume mount [${folderRes.name}] with path [${folderRes.path}] from asset [${asset.enterprise}/${asset.name}]`);
                this._ui.userMessage(`Successfully deleted volume mount [${folderRes.name}] with path [${folderRes.path}] from asset [${asset.enterprise}/${asset.name}]`);
            }
            else if (result.error) {
                this.logger.error(`Error deleting volume mount [${folderRes.name}]: ${result.message || ""}`, result.error);
                this._ui.userMessage(`Error deleting volume mount [${folderRes.name}] with path [${folderRes.path}] from asset [${asset.enterprise}/${asset.name}]: ${result.message || ""}; ${result.error.message || result.error.stack}`);
                throw result.error;
            }
            else {
                const msg = `Failed without error to delete volume mount [${folderRes.name}]: ${result.message || ""}`;
                this.logger.warn(msg);
                this._ui.userMessage(`Failed without error to delete volume mount [${folderRes.name}] with path [${folderRes.path}] from asset [${asset.enterprise}/${asset.name}]: ${result.message || ""}`);
                throw new Error(msg);
            }
        });
    }
    promptForAsset(assets, current) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            let selected = current;
            let changed = false;
            if (assets.length === 0) {
                throw new Error("This enterprise has no assets. You must create an asset to run this command.");
            }
            if (selected != undefined) {
                let found = assets.find(x => x.name === selected);
                if (found == undefined) {
                    selected = undefined;
                }
            }
            if (selected == undefined) {
                if (assets.length === 1) {
                    selected = assets[0].name;
                }
                else {
                    let choices = assets.map(a => { return { name: a.name, value: a.name }; });
                    selected = (yield this._ui.promptSelect("asset", "Asset: ", choices));
                }
                changed = Boolean(current != undefined);
            }
            return [selected, changed];
        });
    }
}
exports.default = AssetVolumeDelete;
AssetVolumeDelete.description = 'Deletes an existing volume mount in the asset.';
AssetVolumeDelete.aliases = ['asset:vol:delete', 'asset:volumes:delete', 'asset:volume:del', 'asset:vol:del', 'asset:volumes:del'];
AssetVolumeDelete.flags = {
    help: core_1.Flags.help({ char: 'h' }),
    name: core_1.Flags.string({ char: 'n', required: false, description: "Moniker for identifying, retrieving, and accessing the folder mapping to delete. Must be unique for the asset." }),
    asset: core_1.Flags.string({ char: 'a', required: false, description: "The name of the asset from which to delete the volume mount." }),
    enterprise: core_1.Flags.string({ char: 'e', description: 'The name of the enterprise to which the asset belongs (required only if more than one enterprise exists).' }),
    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.' }),
};
AssetVolumeDelete.args = {};
AssetVolumeDelete.examples = [
    { description: "Select and delete a volume mount interactively.", command: "<%= config.bin %> <%= command.id %>" },
    { description: "Delete a named volume mount.", command: "<%= config.bin %> <%= command.id %> -e myEnterprise -n myMount --silent" },
    { description: "Renders the equivalent silent command without executing.", command: "<%= config.bin %> <%= command.id %> -e myEnterprise -n myMount --to-script" },
];
//# sourceMappingURL=delete.js.map