"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DockerHubResourceConfigurator = void 0;
const tslib_1 = require("tslib");
const inversify_1 = require("inversify");
const codiac_common_1 = require("@codiac.io/codiac-common");
const codiac_domain_1 = require("@codiac.io/codiac-domain");
const image_registry_1 = require("@codiac.io/codiac-domain/image-registry");
const codiac_relay_1 = require("../../apis/codiac-relay");
const INTERFACES_CLI_1 = require("../../ops/INTERFACES_CLI");
const codiac_ops_common_1 = require("@codiac.io/codiac-ops-common");
const type_safety_utils_1 = require("../../uilogic/type-safety-utils");
/** Walks the user through the selection of an existing
 * or the declaration of a new image registry.
 */
let DockerHubResourceConfigurator = class DockerHubResourceConfigurator {
    constructor(codiacUser, relayClient, _ui, _styler, logger) {
        this.codiacUser = codiacUser;
        this.relayClient = relayClient;
        this._ui = _ui;
        this._styler = _styler;
        this.logger = logger;
        this.cloudProvider = codiac_domain_1.CloudProviderEnum.dockerHub;
        /** Currently supporting only a single reg type per cloud provider. */
        this.regType = codiac_domain_1.ImageRegistryTypes.dockerHub;
    }
    captureImageRegistry() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            return new Promise((resolve, reject) => tslib_1.__awaiter(this, void 0, void 0, function* () {
                let registry;
                try {
                    let isMyOwn = yield this._ui.promptConfirm("regDockerIsCommunity", "Your own? (hit 'n' for community images)", true);
                    if (isMyOwn) {
                        let orgCode = (yield this._ui.prompt("regDockerOrgName", "Organization scope prefix", true));
                        registry = new image_registry_1.DockerHubOrgImageRegistry(orgCode);
                        registry.pullRequiresAuth = true;
                        registry.url = 'index.docker.io';
                    }
                    else {
                        let isOfficial = yield this._ui.promptConfirm("regDockerIsOfficial", "DockerHub's 'Official' images ?", true);
                        registry = new image_registry_1.DockerHubPublicImageRegistry(isOfficial);
                        registry.pullRequiresAuth = false; // official and public images dont require auth to pull
                    }
                    resolve(registry);
                }
                catch (err) {
                    // this.logger.error(`${err.name ?? ''} ${err.message ?? ''}`, err.stack);
                    reject(err);
                }
            }));
        });
    }
    promptToLogin(options) {
        var _a, _b;
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            try {
                let providerSubscriptionId = options === null || options === void 0 ? void 0 : options.providerSubscriptionId;
                let suppressConfirmations = options === null || options === void 0 ? void 0 : options.suppressConfirmations;
                let providedUserName = options === null || options === void 0 ? void 0 : options.providedUserName;
                let providedSecret = options === null || options === void 0 ? void 0 : options.providedSecret;
                let isAuthed = false;
                let userName = undefined;
                let secret = undefined;
                if (!suppressConfirmations) {
                    this._ui.userMessage(`Enter your credentials for ${this._styler.hilite(this.cloudProvider)}`);
                    userName = yield this._ui.prompt('regUsername', "Username: ", false);
                    if (userName === undefined || userName === "")
                        userName = "<token>"; // TODO: make username nullable on the authPvd, so this becomes the job of the auth provider
                    secret = yield this._ui.promptPassword('regSecret', `Password (or token): `);
                }
                else {
                    if (!providedUserName || !providedSecret)
                        throw new Error("Must provide cloud provider username/pwd to login silent mode");
                    userName = providedUserName;
                    secret = providedSecret;
                }
                try {
                    this._ui.startSpinner(`Authenticating with ${this.cloudProvider}...`);
                    let authResult = yield this.relayClient.Call.csp_login({ providerCode: this.cloudProvider, username: userName, secret: secret });
                    if (authResult.error)
                        throw authResult.error;
                    if (type_safety_utils_1.TypeSafetyUtils.toBoolean(authResult.success) == true) {
                        this._ui.stopSpinner("Success!");
                        isAuthed = true;
                    }
                    else {
                        this.logger.debug("Authentication failed".concat(authResult.message ? ": " + authResult.message : "."));
                        this._ui.stopSpinner("Failed.");
                    }
                }
                catch (err) {
                    this.logger.debug(`Error authenticating with ${this.cloudProvider}: ${(_a = err.name) !== null && _a !== void 0 ? _a : ""} ${(_b = err.message) !== null && _b !== void 0 ? _b : ""}`);
                    this._ui.stopSpinner("Failed.");
                }
                if (isAuthed)
                    this._ui.userMessage(`Logged into ${this._styler.hilite(this.cloudProvider)} as [${this._styler.hilite(userName !== null && userName !== void 0 ? userName : "token")}]`);
                // let subxId = await this.promptForSubscriptionId(userName, providerSubscriptionId);
                let cspUser = {
                    tenantCode: this.codiacUser.tenantCode,
                    provider: this.cloudProvider,
                    username: userName,
                    // subscriptionId: undefined,  // Not yet applicable yet for dockerHub client
                    created: new Date(Date.now())
                };
                return [isAuthed, cspUser];
            }
            catch (err) {
                throw err;
            }
        });
    }
    assembleLoginRequest(userName, secret, subscriptionId, proprietaryInput) {
        return { providerCode: this.cloudProvider, username: userName, secret: secret }; // just a pass-thru - doesnt do anything special.
    }
    promptToLogout() {
        return tslib_1.__awaiter(this, void 0, void 0, function* () {
            throw new Error("Interactive logout is not implemented for Docker.");
        });
    }
};
DockerHubResourceConfigurator = tslib_1.__decorate([
    (0, inversify_1.injectable)(),
    tslib_1.__param(0, (0, inversify_1.inject)(codiac_ops_common_1.UserNameTenantCode)),
    tslib_1.__param(1, (0, inversify_1.inject)(codiac_relay_1.RelayClient)),
    tslib_1.__param(2, (0, inversify_1.inject)(INTERFACES_CLI_1.INTERFACES_CLI.IUserInputProvider)),
    tslib_1.__param(3, (0, inversify_1.inject)(INTERFACES_CLI_1.INTERFACES_CLI.IOutputStyler)),
    tslib_1.__param(4, (0, inversify_1.inject)(codiac_common_1.INTERFACES.IBetterLogger)),
    tslib_1.__metadata("design:paramtypes", [codiac_ops_common_1.UserNameTenantCode,
        codiac_relay_1.RelayClient, Object, Object, Object])
], DockerHubResourceConfigurator);
exports.DockerHubResourceConfigurator = DockerHubResourceConfigurator;
//# sourceMappingURL=docker-hub-resource-configurator.js.map