import { __assign } from "tslib";
import axios from 'axios';
import { WindowErrorHandler } from '../errors/window-error-handler';
import * as strUtils from '../str/str';
import { serializeParams } from './http-param-serializer';
var AUTHORIZATION_HEADER = 'Authorization';
export var NO_TIMEOUT = 0;
var HttpService = /** @class */ (function () {
    function HttpService(options) {
        this.options = options;
        this.instance = axios.create();
        if (this.options) {
            // timeout
            if (!this.options.timeout) {
                this.instance.defaults.timeout = 30000;
            }
            else if (this.options.timeout === NO_TIMEOUT) {
                this.instance.defaults.timeout = undefined;
            }
            else {
                this.instance.defaults.timeout = this.options.timeout;
            }
            // request interceptor for authorization header
            if (this.options.protectedUrls && this.options.authorizationFn) {
                var protectedUrls_1 = this.options.protectedUrls;
                var authFn_1 = this.options.authorizationFn;
                this.instance.interceptors.request.use(function (config) {
                    var result = Promise.resolve(config);
                    var tokenAsync;
                    protectedUrls_1.every(function (url) {
                        if (strUtils.startsWith(config.url, url)) {
                            tokenAsync = Promise.resolve(authFn_1());
                            return false; // break
                        }
                        return true;
                    });
                    if (tokenAsync) {
                        result = tokenAsync.then(function (token) {
                            var _a;
                            config.headers = Object.assign(config.headers || {}, (_a = {}, _a[AUTHORIZATION_HEADER] = token, _a));
                            return config;
                        });
                    }
                    return result;
                });
            }
            // response interceptor to progagate PromiseError
            if (this.options.useEventOnPromiseError === undefined || this.options.useEventOnPromiseError) {
                this.instance.interceptors.response.use(function (response) { return response; }, function (err) {
                    // wrap to a PromiseError, so that propagation can be stopped
                    var promiseErrorEvent = new ErrorEvent('error', {
                        error: err,
                        cancelable: true
                    });
                    // delay onError
                    WindowErrorHandler.onError(promiseErrorEvent, true);
                    return Promise.reject(promiseErrorEvent);
                });
            }
        }
    }
    HttpService.prototype.execute = function (config, axiosOptions) {
        var mergedConfig = this.buildConfig(config);
        mergedConfig = __assign(__assign({}, mergedConfig), axiosOptions);
        return this.instance.request(mergedConfig);
    };
    HttpService.prototype.buildConfig = function (config) {
        var _a;
        var axiosConfig = {};
        axiosConfig.url = this.resolveUrl(config);
        axiosConfig.method = config.method;
        axiosConfig.params = config.params;
        axiosConfig.headers = config.headers;
        axiosConfig.timeout = config.timeout;
        if (config.formParams) {
            var CONTENT_TYPE = 'Content-Type';
            var FORM_URLENCODED = 'application/x-www-form-urlencoded';
            if (axiosConfig.headers) {
                axiosConfig.headers[CONTENT_TYPE] = FORM_URLENCODED;
            }
            else {
                axiosConfig.headers = (_a = {},
                    _a[CONTENT_TYPE] = FORM_URLENCODED,
                    _a);
            }
            axiosConfig.data = serializeParams(config.formParams);
        }
        else {
            axiosConfig.data = config.data;
        }
        if (!config.ignoreParamsSerializer) {
            axiosConfig.paramsSerializer = function (params) { return serializeParams(params); };
        }
        return axiosConfig;
    };
    HttpService.prototype.resolveUrl = function (config) {
        var result = config.rawUrl;
        if (result && config.pathParams) {
            for (var key in config.pathParams) {
                result = result.replace('{' + key + '}', encodeURIComponent(config.pathParams[key]));
            }
        }
        return result;
    };
    return HttpService;
}());
export { HttpService };
var HttpPlugin = {
    install: function (v, options) {
        var http = new HttpService(options);
        (v.prototype).$http = http;
    }
};
export default HttpPlugin;
//# sourceMappingURL=http.js.map