"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.EndpointRequest = void 0;
const axios_1 = __importDefault(require("axios"));
const isString_1 = __importDefault(require("lodash/isString"));
const url_1 = require("url");
const common_1 = require("@refinitiv-data/common");
const constants_1 = require("../../constants");
const util_1 = require("../../util");
const render_endpoint_url_1 = require("../../util/render-endpoint-url");
const default_session_1 = require("../../session/default-session");
const url_join_1 = __importDefault(require("url-join"));
class EndpointRequest {
    /** @internal */
    constructor(requestParams) {
        this.requestParams = requestParams;
        (0, util_1.validateRequired)(requestParams, ['url'], 'EndpointRequestDefinitionParams');
    }
    get url() {
        return this.requestParams.url;
    }
    get method() {
        return this.requestParams.method || common_1.HttpMethod.GET;
    }
    get query() {
        return this.requestParams.queryParameters;
    }
    get body() {
        return this.requestParams.bodyParameters;
    }
    get path() {
        return this.requestParams.pathParameters;
    }
    get headers() {
        return this.requestParams.headerParameters;
    }
    get handleAutoRedirect() {
        return this.requestParams.handleAutoRedirect;
    }
    static Definition(params) {
        return new EndpointRequest((0, isString_1.default)(params) ? { url: params } : params);
    }
    static parseUrl(endpointUrl, pathParams) {
        const renderedUrl = (0, render_endpoint_url_1.renderEndpointUrl)(endpointUrl, pathParams);
        return (0, url_1.parse)(renderedUrl, true);
    }
    static prepareEndpointResponse(httpResponse) {
        return {
            httpHeaders: httpResponse.headers,
            httpStatus: httpResponse.status,
            data: httpResponse.data,
        };
    }
    async getData(session = (0, default_session_1.getDefault)()) {
        var _a, _b, _c;
        (0, util_1.validateRequired)({ session }, ['session'], 'EndpointRequestDataParams');
        if (!session.isEndpointSupported) {
            throw new Error(constants_1.ErrorMessages.ONLY_STREAMING_CONNECTION);
        }
        const _d = this.requestParams, { url: endpointUrl, method = common_1.HttpMethod.GET, pathParameters = {}, queryParameters = {}, handleAutoRedirect, bodyParameters, headerParameters } = _d, httpParams = __rest(_d, ["url", "method", "pathParameters", "queryParameters", "handleAutoRedirect", "bodyParameters", "headerParameters"]);
        const { pathname, query: queryFromUrl } = EndpointRequest.parseUrl(endpointUrl, pathParameters);
        const queryParams = Object.assign(Object.assign({}, queryFromUrl), queryParameters);
        const requestConfig = Object.assign(Object.assign(Object.assign({ method, url: EndpointRequest.formatUrl(pathname, session) }, (Object.keys(queryParams).length && { query: queryParams })), httpParams), (handleAutoRedirect !== undefined && { handleAutoRedirect }));
        if (bodyParameters) {
            requestConfig.body = bodyParameters;
        }
        if (headerParameters) {
            requestConfig.headers = headerParameters;
        }
        try {
            const httpResponse = await session.sendRequest(requestConfig);
            return EndpointRequest.prepareEndpointResponse(httpResponse);
        }
        catch (error) {
            const errorDescription = (_c = (_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.message;
            if (errorDescription) {
                error.message += `. ${errorDescription}`;
            }
            if (axios_1.default.isAxiosError(error)) {
                this.handleAxiosError(error);
            }
            throw error;
        }
    }
    // in browsers Axios sometimes returns empty string in 'response.statusText'
    handleAxiosError(error) {
        const { response } = error;
        if (!(response === null || response === void 0 ? void 0 : response.statusText) && (response === null || response === void 0 ? void 0 : response.status) === common_1.HttpCode.BAD_REQUEST) {
            response.statusText = 'Bad Request';
        }
    }
    static formatUrl(url, session) {
        if (session.rdpUrlRoot) {
            return url.startsWith(constants_1.UDF_ENDPOINT_ROOT) || url.startsWith(constants_1.TSI_ENDPOINT_ROOT) ? url : (0, url_join_1.default)(session.rdpUrlRoot, url);
        }
        return url;
    }
}
exports.EndpointRequest = EndpointRequest;
EndpointRequest.Method = common_1.HttpMethod;
//# sourceMappingURL=data:application/json;base64, 