"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransportPipe = void 0;
const qs_1 = __importDefault(require("qs"));
const common_1 = require("@refinitiv-data/common");
const container_session_1 = require("../../constants/container-session");
const error_messages_1 = require("../../constants/error-messages");
const get_position_1 = require("../../util/get-position");
const jet_bus_browser_1 = require("./jet-bus-browser/jet-bus-browser");
const content_1 = require("../../constants/content");
const CONTENT_TYPE_HEADER_NAME = 'Content-Type';
class TransportPipe {
    constructor(bus, options) {
        this.options = options;
        this.isInitialized = false;
        this.bus = bus || new jet_bus_browser_1.JETBusBrowser();
        this.busRequester = new common_1.IpcBusRequester(this.bus, common_1.ContainerSessionService.ApiProxy, this.options);
    }
    async initialize() {
        await this.busRequester.connect();
        this.isInitialized = true;
    }
    async authorize(authParams) {
        if (!this.isInitialized) {
            throw new Error(error_messages_1.ErrorMessages.INITIALIZE_FIRST);
        }
        await this.busRequester.request(common_1.ContainerSessionChannel.Authorize, authParams);
        this.authParams = authParams;
    }
    async cleanUp() {
        await this.busRequester.disconnect();
    }
    /**
     * Get the prefix of URL for RDP requests
     */
    get rdpUrlRoot() {
        return container_session_1.RDP_ENDPOINT_ROOT;
    }
    async request(requestParams) {
        const { url, query } = requestParams, restParams = __rest(requestParams, ["url", "query"]);
        const arrayFormat = url.startsWith(content_1.HISTORICAL_PRICING_URL) ? 'comma' : 'repeat';
        const urlWithQueryParams = query ? `${url}?${qs_1.default.stringify(query, { arrayFormat })}` : url;
        const headers = this.prepareRequestHeaders(requestParams);
        const params = Object.assign(Object.assign({}, restParams), { headers, url: urlWithQueryParams, appKey: this.authParams.appKey, scope: this.authParams.scope });
        const response = await this.busRequester.request(common_1.ContainerSessionChannel.Request, params);
        const httpResponse = this.toHttpResponse(response);
        this.validateResponseStatus(httpResponse);
        return httpResponse;
    }
    /**
     * execEnv was added in eapi-4132 in order to connect to df-streaming
     * Delete in future changes related to CSM and df-streaming connection
     */
    getStreamTransport(api, protocol, execEnv) {
        if (protocol !== 'tr_json2' && protocol !== 'rdp_streaming') {
            throw new Error(`"${protocol}" streaming connection type is not supported!`);
        }
        const channel = protocol === 'tr_json2' && execEnv && execEnv !== container_session_1.ExecutionContainer.DESKTOP_RW_NON_1_9_OR_EIKON
            ? '/api-proxy/stream'
            : common_1.ContainerSessionChannel.Stream;
        return () => {
            const client = new common_1.IpcBusSocketClient(this.bus, channel, api, protocol, this.options);
            client.connect();
            return client;
        };
    }
    getStreamLoginParams() {
        return {
            applicationId: void 0,
            position: (0, get_position_1.getPosition)(),
            appKey: this.authParams.appKey,
        };
    }
    validateResponseStatus(response) {
        const { status } = response;
        if (status >= common_1.HttpCode.OK && status < common_1.HttpCode.MULTIPLE_CHOICES) {
            return;
        }
        const error = new Error(`Request failed with status code ${status}`);
        Object.assign(error, response);
        throw error;
    }
    prepareRequestHeaders(requestParams) {
        const headers = requestParams.headers || {};
        if (typeof requestParams.body === 'object') {
            const contentType = Object.keys(headers).find((header) => header.toUpperCase() === CONTENT_TYPE_HEADER_NAME.toUpperCase());
            if (!contentType) {
                headers[CONTENT_TYPE_HEADER_NAME] = 'application/json';
            }
        }
        return headers;
    }
    toHttpResponse(response) {
        let data;
        try {
            data = response.body ? JSON.parse(response.body) : response.body;
        }
        catch (err) {
            data = response.body;
        }
        const result = {
            config: {},
            headers: response.headers || {},
            statusText: response.statusMessage || 'OK',
            status: response.statusCode,
            data,
        };
        return result;
    }
}
exports.TransportPipe = TransportPipe;
//# sourceMappingURL=data:application/json;base64, 