"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const core_1 = require("@oclif/core");
const autocomplete = require("inquirer-autocomplete-prompt");
const contracts_1 = require("../../../apis/codiac-api/contracts");
const contracts_2 = require("@codiac.io/codiac-common/contracts");
const command_base_enterprise_1 = require("../../../command-base-enterprise");
const cloud_resource_configurator_factory_1 = require("../../../uilogic/cloud-resource-configurator-factory");
const cloud_provider_contextualizer_1 = require("../../../uilogic/cloud-provider-contextualizer");
const image_registry_contextualizer_1 = require("../../../uilogic/image-registry-contextualizer");
const image_contextualizer_1 = require("../../../uilogic/image-contextualizer");
// Has to be module-scoped bc the autocomplete redefines "this", so we can't use it inside searchPorts().
let ports = [];
class ImageRegistryPullSecretUnset extends command_base_enterprise_1.CommandBaseEnterprise {
    bootstrap() {
        super.bootstrap();
        cloud_provider_contextualizer_1.CloudProviderContextualizer.bootstrap(this.ioc);
        this.ioc.bind(image_registry_contextualizer_1.ImageRegistryContextualizer).toSelf();
        this.ioc.bind(image_contextualizer_1.ImageContextualizer).toSelf();
    }
    // --------------------------------------------------------------------
    // Lazy-loaded properties
    get uiRegistry() {
        if (this._uiRegistry_backer === undefined) {
            this._uiRegistry_backer = this.ioc.get(image_registry_contextualizer_1.ImageRegistryContextualizer);
        }
        return this._uiRegistry_backer;
    }
    // --------------------------------------------------------------------
    run() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.bootstrap();
            const { args, flags } = yield this.parse(ImageRegistryPullSecretUnset);
            return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                try {
                    this._userCntx = yield this.establishTenantContext(this._userCntx);
                    let isPrimary = flags.item === "primary";
                    // TODO: Revisit for pull secrets on kits
                    // overlay given values
                    let registries = yield this._codiacApi.ImageRegistry.readMany({ all: true }, { throwNotFound: false });
                    if (registries.length === 0) {
                        throw new Error(`Cannot set pull secrets: No image registries are defined yet.`);
                    }
                    let candidate;
                    if (flags.silent == true) {
                        candidate = this.buildCandidate_silently(isPrimary, flags.registry, registries);
                    }
                    else {
                        candidate = yield this.buildCandidate_interactively(isPrimary, flags.registry, registries);
                    }
                    // FINAL EXECUTION (or not)
                    if (candidate !== undefined) {
                        if (flags.toScript === true) {
                            let script = this.buildScript(candidate);
                            this._ui.userMessage(script);
                        }
                        else {
                            yield this.removePullSecret(candidate.isPrimary, registries.find(r => r.code === candidate.regCode));
                        }
                    }
                    else {
                        this.logger.notice(`Operation cancelled. No work was done.`);
                        this._ui.userMessage(`Operation cancelled. No work was done.`);
                    }
                }
                catch (err) {
                    this.handleError(err);
                }
                finally {
                    yield this.closeConnections();
                    resolve();
                }
            }));
        });
    }
    buildCandidate_silently(isPrimary, regCode, registries) {
        // Rough validation for missing args
        if (!regCode)
            throw new Error("A registry code must be set");
        if (!registries.find(r => r.code === regCode)) {
            throw new Error(`No ImageRegistry record currently exists with code: [${regCode}]. You might need to check your spelling or capture your image registry.`);
        }
        try {
            // TODO: Validate existence of secretRef in the secretStore
            return { isPrimary: isPrimary, regCode: regCode };
        }
        catch (err) {
            throw err;
        }
    }
    /** Walks the user through a Q & A to build out the specs for the asset. */
    buildCandidate_interactively(isPrimary, regCode, registries, allowAddSecrets = false) {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                var _a;
                let candidate;
                try {
                    cloud_resource_configurator_factory_1.RegistryConfiguratorFactory.bootstrap(this.ioc);
                    let partial = {
                        isPrimary: isPrimary,
                        regCode: regCode
                    };
                    let regInput = {};
                    if (partial.regCode) {
                        let found = registries.find(r => r.code === partial.regCode);
                        if (found)
                            regInput = found;
                    }
                    let confirmed;
                    while (!confirmed) {
                        // NOTE:  We are gating on "confirmed != undefined" because that means they asked to revise the values. 
                        console.clear();
                        // REGISTRY  (we've already gated this method for registries.length > 0)
                        let keepRegistry = false;
                        let selectedRegistry;
                        while (keepRegistry === false) {
                            keepRegistry = (partial.regCode === undefined) ? false : yield this._ui.promptConfirm("keepRegistry", `${this._styler.hilite(partial.regCode)} pull secret`);
                            if (!keepRegistry) {
                                selectedRegistry = (yield this.uiRegistry.promptForExistingRegistry(contracts_1.PackageType.container, false, registries));
                                partial.regCode = selectedRegistry.code;
                                keepRegistry = true;
                            }
                            // PRIMARY/SECONDARY
                            let choices = [];
                            if ((selectedRegistry === null || selectedRegistry === void 0 ? void 0 : selectedRegistry.pullSecret) !== undefined && (selectedRegistry === null || selectedRegistry === void 0 ? void 0 : selectedRegistry.pullSecret) !== null) {
                                choices.push({ name: "Primary", value: true });
                            }
                            if ((selectedRegistry === null || selectedRegistry === void 0 ? void 0 : selectedRegistry.pullSecretSecondary) !== undefined && (selectedRegistry === null || selectedRegistry === void 0 ? void 0 : selectedRegistry.pullSecretSecondary) !== null) {
                                choices.push({ name: "Secondary", value: false });
                            }
                            if (choices.length > 1) {
                                partial.isPrimary = (_a = partial.isPrimary) !== null && _a !== void 0 ? _a : true;
                                let keepPrimary = yield this._ui.promptConfirm("keepPrimary", `${this._styler.hilite(partial.isPrimary ? "Primary" : "Secondary")} pull secret`);
                                if (!keepPrimary) {
                                    partial.isPrimary = (yield this._ui.promptSelect("isPrimary", "Which pull secret?: ", [{ name: "Primary", value: true }, { name: "Secondary", value: false }]));
                                }
                            }
                            else if (choices.length === 1) {
                                if (partial.isPrimary && choices[0].name !== "Primary") {
                                    this._ui.userMessage(this._styler.colorWarning(`The image registry [${selectedRegistry === null || selectedRegistry === void 0 ? void 0 : selectedRegistry.code}] has no primary pull secret set.`));
                                    partial.isPrimary = false; // switch to secondary
                                }
                                if (partial.isPrimary === false && choices[0].name !== "Secondary") {
                                    this._ui.userMessage(this._styler.colorWarning(`The image registry [${selectedRegistry === null || selectedRegistry === void 0 ? void 0 : selectedRegistry.code}] has no secondary pull secret set.`));
                                    partial.isPrimary = true; // switch to primary
                                }
                                // this._ui.userMessage(`Remove ${this._styler.hilite(partial.isPrimary ? "Primary" : "Secondary")} pull secret`);
                            }
                            else if (choices.length === 0) {
                                this._ui.userMessage(this._styler.colorWarning(`The ${selectedRegistry === null || selectedRegistry === void 0 ? void 0 : selectedRegistry.type} image registry [${selectedRegistry === null || selectedRegistry === void 0 ? void 0 : selectedRegistry.code}] has no pull secrets set.`));
                                if (registries.length > 1) {
                                    this._ui.userMessage(`Choose another registry (or hit CTRL-C to cancel)...`);
                                }
                                else {
                                    this.exit();
                                }
                                keepRegistry = false;
                                partial.regCode = undefined;
                            }
                        }
                        candidate = {
                            isPrimary: partial.isPrimary,
                            regCode: partial.regCode
                        };
                        // this.logger.notice(prettify(candidate));
                        this._ui.userMessage(`You are about to remove the ${this._styler.hilite(candidate.isPrimary ? "primary" : "secondary")} pull secret for ${this._styler.bold(this._styler.hilite(candidate.regCode))} [Tenant: ${this._userCntx.currentTenantCode}].`);
                        confirmed = yield this._ui.promptConfirm("confirmPullSecret", "Continue?", false);
                    }
                    if (candidate === undefined)
                        throw new Error("No PullSecret was defined."); // this shd never happen; it's just here to pacify typescript.
                    resolve(candidate);
                }
                catch (err) {
                    // this.logger.error(`${err.name ?? ''} ${err.message ?? ''}`, err.stack);
                    reject(err);
                }
            }));
        });
    }
    removePullSecret(isPrimary, registry) {
        return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
            var _a;
            try {
                let pullSecretField = isPrimary ? "pullSecret" : "pullSecretSecondary";
                let patchSpec = {
                    id: registry.id,
                    operations: [
                        {
                            op: contracts_2.patchOperationType.replace,
                            path: pullSecretField,
                            value: undefined
                        }
                    ]
                };
                let result = yield this._codiacApi.ImageRegistry.tryPatch(patchSpec);
                if (result.success) {
                    this._ui.userMessage(`Successfully removed ${this._styler.hilite(isPrimary ? "primary" : "secondary")} pull secret on ${registry.type} image registry [${this._styler.hilite(registry.code)}]`);
                }
                else if (result.error) {
                    this._ui.userMessage(`${this._styler.colorCritical("Error")} removing ${isPrimary ? "primary" : "secondary"} pull secret on ${registry.type} image registry [${registry.code}]: ${result.error.name} ${(_a = result.error.message) !== null && _a !== void 0 ? _a : result.error.stack}`);
                }
                resolve();
            }
            catch (err) {
                this.logger.error(err, registry);
                resolve();
                // reject(err);
            }
        }));
    }
    buildScript(candidate) {
        let output;
        try {
            output = `codiac imageRegistry:pullSecret:unset --silent`;
            let args;
            let flags = {};
            flags.registry = candidate.regCode;
            if (candidate.isPrimary !== true)
                flags.item = "secondary";
            Object.keys(flags).forEach(k => output = output.concat(" ", `--${k}=${flags[k]}`));
            return output;
        }
        catch (err) {
            throw err;
        }
    }
}
exports.default = ImageRegistryPullSecretUnset;
ImageRegistryPullSecretUnset.description = 'Removes the primary or secondary pull secret reference for the given container registry.';
ImageRegistryPullSecretUnset.aliases = ['pullsecret:unset'];
ImageRegistryPullSecretUnset.dependsOn = ["registry", "storeType", "storeName", "name"];
ImageRegistryPullSecretUnset.flags = {
    // kit: Flags.string({ char: 'k', required: false, exclusive: ["image", "registry"], description: "The name of the kit (with library prefix, eg: 'library/kitName') to use to create the asset.  Use '?' to be prompted for a kit (Optional: used instead of calling for the image)." }),
    registry: core_1.Flags.string({ char: 'r', required: false, exclusive: ["kit"], description: "The container registry in which the image exists (defaults to docker hub)." }),
    // name: Flags.string({ char: 'n', required: false, description: "The name to give the enterprise asset (Optional: defaults to the image name without the scope prefix)." }),
    // code: 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)." }),
    // enterprise: Flags.string({ char: 'e', required: false, description: 'The name of the enterprise in which to create this asset. (defaults to the current enterprise context)' }),
    item: core_1.Flags.string({ char: 'f', options: ["primary", "secondary"], required: false, default: "primary", description: "Applies the command to either the primary (default) or seoncdary secret for the image registry." }),
    toScript: core_1.Flags.boolean({ char: 'z', required: false, description: `Outputs an assembled command string, NO execution` }),
    silent: core_1.Flags.boolean({ char: 'y', dependsOn: ImageRegistryPullSecretUnset.dependsOn, required: false, description: `(Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs. Requires: ${ImageRegistryPullSecretUnset.dependsOn}` }),
    help: core_1.Flags.help({ char: 'h' })
};
ImageRegistryPullSecretUnset.args = {};
//# sourceMappingURL=unset.js.map