"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 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");
const type_safety_utils_1 = require("../../uilogic/type-safety-utils");
// Has to be module-scoped bc the autocomplete redefines "this", so we can't use it inside searchPorts().
let ports = [];
class ImageRegistryCapture 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();
        // .toDynamicValue(() => new ImageRegistryContextualizer(this.cspContextualizer, this._codiacApi, this.genRelayClient, this._ui, this._styler, this.logger));
        this.ioc.bind(image_contextualizer_1.ImageContextualizer)
            .toSelf();
        // .toDynamicValue(() => new ImageContextualizer(this._ui, this._styler, this.genRelayClient, this.logger));
    }
    // --------------------------------------------------------------------
    // Lazy-loaded properties
    get uiRegistry() {
        if (this._uiRegistry_backer === undefined) {
            this._uiRegistry_backer = this.ioc.get(image_registry_contextualizer_1.ImageRegistryContextualizer);
            // this._uiRegistry_backer = new ImageRegistryContextualizer(this.cspContextualizer, this._codiacApi, this.genRelayClient, this._ui, this._styler, this.logger);
        }
        return this._uiRegistry_backer;
    }
    // --------------------------------------------------------------------
    run() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            this.bootstrap();
            const { args, flags } = yield this.parse(ImageRegistryCapture);
            return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                try {
                    this._userCntx = yield this.establishTenantContext(this._userCntx);
                    let partial = {
                        url: flags.url,
                        provider: (flags.provider) ? type_safety_utils_1.TypeSafetyUtils.toEnum(contracts_1.CloudProviderEnum, flags.provider) : undefined,
                        // type: This is a property, but it isnt an input for the configurator...???
                        code: flags.name
                    };
                    let candidate;
                    if (flags.silent == true) {
                        candidate = this.buildCandidate_silently(partial);
                    }
                    else {
                        candidate = yield this.buildCandidate_interactively(partial);
                    }
                    // FINAL EXECUTION (or not)
                    if (candidate !== undefined) {
                        if (flags.toScript === true) {
                            let script = this.buildScript(candidate);
                            this._ui.userMessage(script);
                        }
                        else {
                            yield this.saveRegistry(candidate);
                        }
                    }
                    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(partial) {
        try {
            throw new Error(`Silent capture not yet implemented`);
            // return candidate;
        }
        catch (err) {
            throw err;
        }
    }
    /** Walks the user through a Q & A to build out the specs for the asset. */
    buildCandidate_interactively(partial) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                // Validate
                if (partial.code) {
                    let alreadyCaptured = yield this._codiacApi.ImageRegistry.readMany({ all: true }, { throwNotFound: false });
                    let found = alreadyCaptured.find(r => r.code === partial.code);
                    if (found)
                        throw new Error(`Image registry [${partial.code}] already exists as [${found.type}, url: ${found.url}]`);
                }
                // configure
                cloud_resource_configurator_factory_1.RegistryConfiguratorFactory.bootstrap(this.ioc);
                let registry = (yield this.uiRegistry.promptForRegistry(contracts_1.PackageType.container, this.ioc, partial, true));
                registry.pullRequiresAuth = type_safety_utils_1.TypeSafetyUtils.toBoolean((_a = registry.pullRequiresAuth) !== null && _a !== void 0 ? _a : true);
                registry.pullRequiresAuth = yield this._ui.promptConfirm("reqAuth", "Is it private (requires authentication to pull images)?", registry.pullRequiresAuth);
                return registry;
            }
            catch (err) {
                // this.logger.error(`${err.name ?? ''} ${err.message ?? ''}`, err.stack);
                throw err;
            }
        });
    }
    saveRegistry(registry) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                let minted = yield this._codiacApi.ImageRegistry.create(registry);
                this.logger.debug(`Successfully captured ${registry.type} image registry [${this._styler.hilite(registry.code)}]`, minted);
                this._ui.userMessage(`Successfully captured ${registry.type} image registry [${this._styler.hilite(registry.code)}]`);
                return;
            }
            catch (err) {
                this._ui.userMessage(`${this._styler.colorCritical("Error")} capturing ${registry.type} image registry [${registry.code}]: ${err.name} ${(_a = err.message) !== null && _a !== void 0 ? _a : err.stack}`);
                this.logger.error(err, registry);
                throw err;
            }
        });
    }
    buildScript(candidate) {
        let output;
        try {
            output = `codiac imageRegistry:capture --silent`;
            let args;
            let flags = {};
            flags.name = candidate.code;
            flags.provider = candidate.provider;
            // ---------------------------------------------------------
            // These properties are NOT yet on the ImageRegistry object; 
            // ARENT THEY NEEDED??? 
            // flags.subscriptionId = candidate.subscriptionId;
            // flags.location = candidate.location;
            // ---------------------------------------------------------
            Object.keys(flags).forEach(k => output = output.concat(" ", `--${k}=${flags[k]}`));
            return output;
        }
        catch (err) {
            throw err;
        }
    }
}
exports.default = ImageRegistryCapture;
ImageRegistryCapture.description = 'Saves a reference to an existing container registry.';
ImageRegistryCapture.aliases = [];
ImageRegistryCapture.dependsOn = ["registry", "storeType", "storeName", "name"];
ImageRegistryCapture.flags = {
    url: core_1.Flags.string({ char: 'u', required: false, description: "The container registry url." }),
    provider: core_1.Flags.string({ char: 'p', options: Object.values(contracts_1.CloudProviderEnum), required: false, description: "The cloud provider hosting the container registry." }),
    name: core_1.Flags.string({ char: 'n', required: false, description: "The resource name of the container registry within the cloud provider subscription." }),
    subscriptionId: core_1.Flags.string({ char: 's', required: false, description: "The id of the cloud provider account in which the registry resides." }),
    location: core_1.Flags.string({ char: 'l', required: false, description: "The data center in which the registry resides (use the code name, eg: in Aws use 'us-east-1', NOT 'Virginia, US')." }),
    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: ImageRegistryCapture.dependsOn, required: false, description: `(Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs. Requires: ${ImageRegistryCapture.dependsOn}` }),
    help: core_1.Flags.help({ char: 'h' })
};
ImageRegistryCapture.args = {};
//# sourceMappingURL=capture.js.map