"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BootstrapperForApiClients = void 0;
require("reflect-metadata");
const codiac_api_1 = require("./apis/codiac-api");
const codiac_relay_1 = require("./apis/codiac-relay");
const uilogic_1 = require("./uilogic");
const entities_1 = require("./ops/entities");
const api_client_plus_local_1 = require("./apis/api-plus-local/api-client-plus-local");
const type_safety_utils_1 = require("./uilogic/type-safety-utils");
const codiac_api_nats_1 = require("./apis/codiac-api-nats");
const codiac_relay_nats_1 = require("./apis/codiac-relay-nats");
const codiac_messaging_1 = require("@codiac.io/codiac-messaging");
class BootstrapperForApiClients {
    static bootstrap(ioc, cmd) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
        const apiClientKind = (_c = (_b = (_a = cmd.localConfig) === null || _a === void 0 ? void 0 : _a.apiClientKind) !== null && _b !== void 0 ? _b : cmd._cliCfg.apiClientKind) !== null && _c !== void 0 ? _c : entities_1.ApiClientKindEnum.nats;
        const useNats = Boolean(apiClientKind == entities_1.ApiClientKindEnum.nats);
        const localEntities = type_safety_utils_1.TypeSafetyUtils.toBoolean(/* TEMP HACK!! --> update this class... */ (_e = (_d = cmd.localConfig) === null || _d === void 0 ? void 0 : _d.localEntities) !== null && _e !== void 0 ? _e : (_f = cmd._cliCfg) === null || _f === void 0 ? void 0 : _f.localEntities);
        // Cant do it this way until we make ApiUserCreds.token nullable.
        // ioc.bind<CodiacClientConfig>(CodiacClientConfig).toConstantValue({ apiBaseUrl: this.codiacApiUrl });
        // ioc.bind(ApiUserCreds).toConstantValue(undefined);  // <--- ILLEGAL!
        // host.ioc.bind<CodiacRestClient>(CodiacRestClient).toSelf();
        // IMPORTANT: Read token from user context at injection time, 
        // NOT at bootstrap time, 
        // so that a freshly authenticated context gets passed into the api client.
        // let authToken = (cmd._userCntx) ? cmd._userCntx.currentToken : undefined;  
        // Codiac Rest Api  
        // (need this in all cases bc this one is also the Auth client)
        codiac_api_1.CodiacRestClient.bootstrap(ioc);
        ioc.bind(codiac_api_1.CodiacRestClient).toDynamicValue(() => { var _a; return codiac_api_1.CodiacRestClient.create(cmd.logger, cmd.codiacApiUrl, (_a = cmd._userCntx) === null || _a === void 0 ? void 0 : _a.currentToken); }); // 
        if (useNats) {
            // NATS
            // Codiac Api
            const givenNatsUrl = (_h = (_g = cmd.localConfig) === null || _g === void 0 ? void 0 : _g.apiNatsUrl) !== null && _h !== void 0 ? _h : cmd._cliCfg.codiacNatsUrl;
            codiac_api_nats_1.CodiacNatsClient.bootstrap(ioc, givenNatsUrl ? { baseUrl: givenNatsUrl } : undefined);
            ioc.bind(codiac_api_nats_1.CodiacNatsClient).toDynamicValue((ctx) => {
                var _a;
                const connector = ctx.container.get(codiac_messaging_1.StreamingConstants.IStreamingConnector);
                const settings = ctx.container.get(codiac_api_nats_1.CodiacNatsClientConfig);
                cmd.hasConnectedYet = true; // Set this to prevent any unnecessary instantiations on closeout or startup.
                return codiac_api_nats_1.CodiacNatsClient.create(cmd.logger, connector, settings, (_a = cmd._userCntx) === null || _a === void 0 ? void 0 : _a.currentToken);
            });
            // Codiac Relay
            codiac_relay_nats_1.RelayNatsClient.bootstrap(ioc, {
                natsInstance: this.RELAY_NATS_INSTANCE,
                requestTimeoutInMs: (_m = (_k = (_j = cmd.localConfig) === null || _j === void 0 ? void 0 : _j.natsRequestTimeoutInMs) !== null && _k !== void 0 ? _k : (_l = cmd._cliCfg) === null || _l === void 0 ? void 0 : _l.natsRequestTimeoutInMs) !== null && _m !== void 0 ? _m : codiac_relay_nats_1.RelayNatsClient.DEFAULTS.requestTimeoutInMs,
                connectTimeoutInMs: (_r = (_p = (_o = cmd.localConfig) === null || _o === void 0 ? void 0 : _o.natsConnectTimeoutInMs) !== null && _p !== void 0 ? _p : (_q = cmd._cliCfg) === null || _q === void 0 ? void 0 : _q.natsConnectTimeoutInMs) !== null && _r !== void 0 ? _r : codiac_relay_nats_1.RelayNatsClient.DEFAULTS.connectTimeoutInMs
            });
            ioc.bind(codiac_relay_nats_1.RelayNatsClient).toDynamicValue((ctx) => {
                var _a;
                const connector = ctx.container.getNamed(codiac_messaging_1.StreamingConstants.IStreamingConnector, this.RELAY_NATS_INSTANCE);
                const settings = ctx.container.get(codiac_relay_nats_1.RelayNatsClientConfig);
                cmd.hasConnectedYet = true; // Set this to prevent any unnecessary instantiations on closeout or startup.
                return codiac_relay_nats_1.RelayNatsClient.create(cmd.logger, connector, settings, (_a = cmd._userCntx) === null || _a === void 0 ? void 0 : _a.currentToken);
            });
            if (localEntities) {
                // TODO: Bootstrap the api-with-local
            }
        }
        else {
            // HTTP
            // Codiac Api
            // see CodiacRestClient bootstrapping above
            // Codiac Relay
            codiac_relay_1.RelayClient.bootstrap();
            ioc.bind(codiac_relay_1.RelayClient).toDynamicValue(() => { var _a; return codiac_relay_1.RelayClient.create(cmd.logger, undefined, (_a = cmd._userCntx) === null || _a === void 0 ? void 0 : _a.currentToken); });
            if (localEntities) {
                // Bootstrap the api-with-local
                const LOCAL_DATA_ROUTE_PREFIX = "/local"; // <--- Must match this same property of the CodiacRelayApi class in the relay.
                ioc.bind(api_client_plus_local_1.ApiClientPlusLocalConfig).toConstantValue({ localDataRoutePrefix: LOCAL_DATA_ROUTE_PREFIX }); // TODO: Consider exposing this in the cli config or the local config like cmd.codiacApiUrl
                ioc.bind(api_client_plus_local_1.ApiClientPlusLocal)
                    .toDynamicValue((ctx) => {
                    var _a;
                    const settings = ctx.container.get(api_client_plus_local_1.ApiClientPlusLocalConfig);
                    return api_client_plus_local_1.ApiClientPlusLocal.createPlus(cmd.genRelayClient, cmd.logger, settings.localDataRoutePrefix, cmd.codiacApiUrl, (_a = cmd._userCntx) === null || _a === void 0 ? void 0 : _a.currentToken);
                });
            }
        }
        // --------------------------------------------------------------------------------------
        // Ultimate RelayClient binding
        // --------------------------------------------------------------------------------------
        if (useNats) {
            ioc.bind(codiac_relay_1.RelayClient).toDynamicValue(ctx => ctx.container.get(codiac_relay_nats_1.RelayNatsClient));
            // hard cast ^ ok bc the client generated clients have diff type syntaxes 
            // (need to fix, but http is going away so its not worth it to fix)
        }
        else {
            // already done above.  TODO: use an interface for relay client
        }
        // --------------------------------------------------------------------------------------
        // Ultimate CodiacClient binding
        // --------------------------------------------------------------------------------------
        //  !!!! IMPORTANT !!!!  
        //  We are using:   `.toDynamicValue(ctx => ctx.container.get(...))`
        //  to preserve the reference to command properties for the dependencies instead of ioc
        //  (this prevents duplicate instances within the execution of a command).
        // --------------------------------------------------------------------------------------
        if (useNats) {
            if (localEntities) {
                ioc.bind(uilogic_1.INTERFACES_CLI_ENTERPRISE.ICodiacClient).toDynamicValue(ctx => ctx.container.get(codiac_api_nats_1.CodiacNatsClient)); // TODO: ApiNatsClientPlusLocal
            }
            else {
                ioc.bind(uilogic_1.INTERFACES_CLI_ENTERPRISE.ICodiacClient).toDynamicValue(ctx => ctx.container.get(codiac_api_nats_1.CodiacNatsClient));
            }
        }
        else {
            if (localEntities) {
                ioc.bind(uilogic_1.INTERFACES_CLI_ENTERPRISE.ICodiacClient).toDynamicValue(ctx => ctx.container.get(api_client_plus_local_1.ApiClientPlusLocal));
            }
            else {
                ioc.bind(uilogic_1.INTERFACES_CLI_ENTERPRISE.ICodiacClient).toDynamicValue(ctx => ctx.container.get(codiac_api_1.CodiacRestClient));
            }
        }
        // -----------------------------------------------------------------------------------------------------------
        // Ultimate Auth Client binding
        // -----------------------------------------------------------------------------------------------------------
        // use the codiac rest client
        ioc.bind(uilogic_1.INTERFACES_CLI_ENTERPRISE.IAuthClient).toDynamicValue(ctx => ctx.container.get(codiac_api_1.CodiacRestClient));
        // -----------------------------------------------------------------------------------------------------------
    }
}
exports.BootstrapperForApiClients = BootstrapperForApiClients;
BootstrapperForApiClients.RELAY_NATS_INSTANCE = "relay";
//# sourceMappingURL=bootstrapper-for-api-clients.js.map