"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");
const codiac_constants_1 = require("./codiac-constants");
class BootstrapperForApiClients {
    static bootstrap(ioc, cmd) {
        // const apiClientKind: ApiClientKindEnum = (<any>cmd.localConfig)?.apiClientKind ?? cmd._cliCfg.apiClientKind ?? ApiClientKindEnum.nats;
        // const useNats = Boolean(apiClientKind == ApiClientKindEnum.nats);
        const useNats = type_safety_utils_1.TypeSafetyUtils.toBoolean(cmd._cliCfg.apiClientKind == entities_1.ApiClientKindEnum.nats);
        // const localEntities = TypeSafetyUtils.toBoolean(/* TEMP HACK!! --> update this class... */(<any>cmd.localConfig)?.localEntities ?? cmd._cliCfg?.localEntities);
        const localEntities = cmd._cliCfg.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 = cmd.localConfig?.apiNatsUrl ?? cmd._cliCfg.codiacNatsUrl;
            // const givenNatsUrl = cmd._cliCfg.codiacNatsUrl!;
            codiac_api_nats_1.CodiacNatsClient.bootstrap(ioc, { baseUrl: cmd._cliCfg.codiacNatsUrl });
            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,
                baseUrl: cmd._cliCfg.useLocalRelay ? codiac_constants_1.CliConstants.LOCAL_RELAY_NATS_URL : cmd._cliCfg.codiacNatsUrl,
                // requestTimeoutInMs: (<any>cmd.localConfig)?.natsRequestTimeoutInMs ?? (<any>cmd._cliCfg)?.natsRequestTimeoutInMs ?? RelayNatsClient.DEFAULTS.requestTimeoutInMs,
                // connectTimeoutInMs: (<any>cmd.localConfig)?.natsConnectTimeoutInMs ?? (<any>cmd._cliCfg)?.natsConnectTimeoutInMs ?? RelayNatsClient.DEFAULTS.connectTimeoutInMs
                requestTimeoutInMs: cmd._cliCfg.natsRequestTimeoutInMs,
                connectTimeoutInMs: cmd._cliCfg.natsConnectTimeoutInMs
            });
            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