"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 codiac_domain_1 = require("@codiac.io/codiac-domain");
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 type_safety_utils_1 = require("../../uilogic/type-safety-utils");
class SecretStoreCapture extends command_base_enterprise_1.CommandBaseEnterprise {
    bootstrap() {
        super.bootstrap();
        // TODO: Move all functionality requiring this bootstrapper into the relay...
        // localConfig?.apiUrl ?? host.appConfig["codiac-base-url"]
        // OpsEnterprise.bootstrap(this.ioc, { baseUrl: this.codiacApiUrl });
        cloud_provider_contextualizer_1.CloudProviderContextualizer.bootstrap(this.ioc);
    }
    run() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                this.bootstrap();
                const { args, flags } = yield this.parse(SecretStoreCapture);
                this._userCntx = yield this.establishTenantContext(this._userCntx);
                let kvpStores = yield this._codiacApi.KvpStoreDef.readMany({ all: true }, { throwNotFound: false });
                let alreadyCaptured = kvpStores.filter(s => [codiac_domain_1.KvpStoreTypesEnum.awsKeyVault, codiac_domain_1.KvpStoreTypesEnum.azKeyVault].map(x => x.toString()).includes(s.type)).map(x => x);
                let partial = {
                    name: flags.name,
                    provider: flags.provider ? type_safety_utils_1.TypeSafetyUtils.toEnum(codiac_domain_1.CloudProviderEnum, flags.provider) : undefined
                    // type: This is a property, but it isnt an input for the configurator...???
                };
                let candidate;
                if (flags.silent == true) {
                    candidate = this.buildCandidate_silently(partial, alreadyCaptured);
                }
                else {
                    candidate = yield this.buildCandidate_interactively(partial, alreadyCaptured);
                }
                // FINAL EXECUTION (or not)
                if (candidate !== undefined) {
                    if (flags.toScript === true) {
                        let script = this.buildScript(candidate);
                        this._ui.userMessage(script);
                    }
                    else {
                        yield this.saveSecretStore(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();
                return;
            }
        });
    }
    buildCandidate_silently(partial, alreadyCaptured) {
        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, alreadyCaptured) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                let candidate;
                cloud_resource_configurator_factory_1.SecretStoreConfiguratorFactory.bootstrap(this.ioc);
                if (partial.name) {
                    let found = alreadyCaptured.find(r => r.name === partial.name);
                    if (found) {
                        return found;
                    }
                }
                let factory = new cloud_resource_configurator_factory_1.SecretStoreConfiguratorFactory(); //this._codiacApi, this._ui, this.logger);
                // 1. Select a cloud resource provider
                // let choices = this.secretClients.getAllProviders()
                let choices = factory.getAllProviders(this.ioc);
                // let choices = await this.relayClient.getAllSecretProviders();
                partial.provider = (yield this.cspContextualizer.promptForCloudProvider(choices, partial.provider));
                // 2. Authenticate with the cloud resource provider
                let subx = (_a = partial.accountId) !== null && _a !== void 0 ? _a : partial.subscriptionId;
                let cspUser = yield this.cspContextualizer.promptForCloudProviderCreds(this.ioc, partial.provider, undefined, undefined, undefined, subx);
                if (cspUser.subscriptionId) {
                    switch (partial.provider) {
                        case codiac_domain_1.CloudProviderEnum.aws:
                            partial.accountId = cspUser.subscriptionId;
                            break;
                        case codiac_domain_1.CloudProviderEnum.azure:
                            partial.subscriptionId = cspUser.subscriptionId;
                            break;
                        default:
                            partial.subscriptionId = cspUser.subscriptionId;
                            break;
                        // TODO: Add the subscriptionId property to the SecretStoreDef domain entity.
                    }
                }
                // 3. Select an existing secret store
                let cfg8r = factory.create(partial.provider, this.ioc);
                // let provisionerFactory = this.ioc.get(ProvisionerFactory);
                // let provisioner = await provisionerFactory.loadSecretStoreProvisioner(partial.provider);
                // candidate = await cfg8r.captureSecretStore(provisioner, partial);
                candidate = yield cfg8r.captureSecretStore(partial);
                return candidate;
            }
            catch (err) {
                // this.logger.error(`${err.name ?? ''} ${err.message ?? ''}`, err.stack);
                throw err;
            }
        });
    }
    saveSecretStore(candidate) {
        var _a;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                let minted = yield this._codiacApi.KvpStoreDef.create(candidate);
                this.logger.debug(`Successfully captured ${candidate.type} secret store [${this._styler.hilite(candidate.name)}]`, minted);
                this._ui.userMessage(`Successfully captured ${candidate.type} secret store [${this._styler.hilite(candidate.name)}]`);
                return;
            }
            catch (err) {
                this._ui.userMessage(`${this._styler.colorCritical("Error")} capturing ${candidate.type} secret store [${candidate.name}]: ${err.name} ${(_a = err.message) !== null && _a !== void 0 ? _a : err.stack}`);
                this.logger.error(err, candidate);
                throw err;
            }
        });
    }
    buildScript(candidate) {
        let output;
        try {
            output = `codiac secretStore:capture --silent`;
            let args;
            let flags = {};
            flags.name = candidate.name;
            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 = SecretStoreCapture;
SecretStoreCapture.description = 'Upserts a reference to an existing secretStore.';
SecretStoreCapture.aliases = ['secretStore'];
SecretStoreCapture.dependsOn = ["registry", "storeType", "storeName", "name"];
SecretStoreCapture.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(codiac_domain_1.CloudProviderEnum), required: false, description: "The cloud provider hosting the secret store." }),
    name: core_1.Flags.string({ char: 'n', required: false, description: "The resource name of the secret store 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 secret store resides (in Aws, this is the 'AccountId')." }),
    location: core_1.Flags.string({ char: 'l', required: false, description: "The region or data center in which the secret store 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: SecretStoreCapture.dependsOn, required: false, description: `(Optional: defaults to false) Prevents confirmations of user-values that are remembered from prior runs. Requires: ${SecretStoreCapture.dependsOn}` }),
    help: core_1.Flags.help({ char: 'h' })
};
SecretStoreCapture.args = {};
//# sourceMappingURL=capture.js.map