"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransportRdp = void 0;
const url_join_1 = __importDefault(require("url-join"));
const common_1 = require("@refinitiv-data/common");
const config_1 = require("../../config");
const logger_1 = require("../../logger");
const lodash_1 = require("lodash");
const stream_login_request_converter_1 = require("../../util/stream-login-request-converter");
const web_socket_url_builder_1 = require("../../util/web-socket-url-builder");
const webSocket_helper_1 = require("../../util/webSocket-helper");
class TransportRdp {
    constructor(params) {
        this.params = params;
        this.isRefreshRequired = true;
        this.log = logger_1.logger.getLogger('transport:rdp');
    }
    get baseUrl() {
        return config_1.config.get('sessions').platform['default-session']['base-url'];
    }
    /**
     *
     * @param api Name of streaming connection in the configuration file. ('streaming/pricing/main, streaming/trading/redi, ...')
     * @param protocol websocket protocol
     */
    async getSocketCreators(api, protocol) {
        return this.requestWebSocketList(api, protocol);
    }
    getStreamLoginParams() {
        const streamAuthParams = {
            dacs: this.params.dacs,
            accessToken: this.params.getAccessToken(),
            userName: this.params.userName,
        };
        return (0, stream_login_request_converter_1.buildRdpSessionLoginData)(streamAuthParams);
    }
    getStreamingDiscoveryEndpoint(api) {
        const [dataApi, service, endpoint] = api.split('/');
        if (!(dataApi && service && endpoint)) {
            throw new Error(`Parameter 'api' is not correct. Please check your config.`);
        }
        const discoveryEndpoint = config_1.config.get(`apis.${dataApi}.${service}`).url || '';
        const path = config_1.config.get(`apis.${dataApi}.${service}.endpoints.${endpoint}.path`) || '/';
        return (0, url_join_1.default)(this.baseUrl, discoveryEndpoint, path);
    }
    getWebSocketLocations(api) {
        const [dataApi, service, endpoint] = api.split('/');
        return config_1.config.get(`apis.${dataApi}.${service}.endpoints.${endpoint}.locations`) || [];
    }
    /**
     *
     * @param api Name of streaming connection in the configuration file. ('streaming/pricing/main, streaming/trading/redi, ...')
     * @param protocol websocket protocol
     */
    async requestWebSocketList(api, protocol) {
        const { data } = await this.params.request({
            url: this.getStreamingDiscoveryEndpoint(api),
            method: common_1.HttpMethod.GET,
        });
        const filteredByProtocol = data.services.filter(service => service.dataFormat.includes(protocol));
        const configLocations = this.getWebSocketLocations(api);
        let endpointsList;
        if (!Array.isArray(configLocations)) {
            throw new Error(`Location ${configLocations} should be Array. Please check your configuration`);
        }
        if (configLocations.length === 0) {
            endpointsList = (0, lodash_1.shuffle)(filteredByProtocol.filter(({ location }) => location.length >= 1));
        }
        else {
            endpointsList = configLocations.map((configLocation) => {
                const endpoint = filteredByProtocol.find(({ location }) => this.isLocationAllowed(location, configLocation));
                if (!endpoint) {
                    throw new Error(`Unknown location: ${configLocation}. Please check your configuration`);
                }
                return endpoint;
            });
        }
        if (endpointsList.length === 0) {
            throw new Error('Could not select endpoint for streaming connection. Please check streaming discovery response');
        }
        this.log.debug('Available WS endpoints', endpointsList.map(({ endpoint }) => endpoint));
        return endpointsList.map(({ endpoint, port }) => (0, webSocket_helper_1.prepareSocketCreator)(this.buildWsUrl(endpoint, parseInt(port, 10)), protocol));
    }
    buildWsUrl(endpoint, port) {
        try {
            return web_socket_url_builder_1.WebSocketUrlBuilderImpl.getNewInstance().setDefaultPathname('/WebSocket').setUrl(endpoint).setPort(port).build();
        }
        catch (err) {
            throw new Error('Unable to create a web socket url!');
        }
    }
    isLocationAllowed(locationsList, value) {
        if (locationsList.length > 1) {
            return locationsList.every(item => item.includes(value));
        }
        return locationsList[0] === value;
    }
}
exports.TransportRdp = TransportRdp;
//# sourceMappingURL=data:application/json;base64, 