"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
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;
};
Object.defineProperty(exports, "__esModule", { value: true });
const url = require("url");
const utils = require("@cobalt-engine/utils");
const got_cjs_1 = require("got-cjs");
const Config_1 = require("../Config");
const Custom_error_1 = require("../Custom-error");
const WizError_1 = require("../WizError");
class Request {
    constructor() {
    }
    get(url, data) {
        return sendRequest('get', url, data);
    }
    post(url, data) {
        return sendRequest('post', url, data);
    }
    put(url, data) {
        return sendRequest('put', url, data);
    }
    delete(url, data) {
        return sendRequest('delete', url, data);
    }
    patch(url, data) {
        return sendRequest('patch', url, data);
    }
}
exports.default = Request;
function sendRequest(method, url, data = {}) {
    return __awaiter(this, void 0, void 0, function* () {
        const config = yield Config_1.Config.get();
        const tenant = config.authServer.realm;
        const { headers = {} } = data, initialOptions = __rest(data, ["headers"]);
        const authorization = data.hasOwnProperty('auth') ? `Bearer ${data.auth.bearer}` : '';
        const options = Object.assign({ url,
            method, headers: Object.assign(Object.assign({}, headers), { tenant }) }, initialOptions);
        if (!options.headers.authorization && authorization) {
            options.headers.authorization = authorization;
        }
        try {
            const { body, statusCode } = yield (0, got_cjs_1.default)(options);
            if ((statusCode < 200) && (statusCode >= 400)) {
                throw new Custom_error_1.default(statusCode);
            }
            return utils.jsonOrText(body);
        }
        catch (error) {
            errorHandler(error, url);
        }
    });
}
function errorHandler(error, url) {
    if (isInvalidUrlError(error)) {
        throw new WizError_1.WizError('INVALID_URL', url);
    }
    else if (isServerError(error)) {
        throw new WizError_1.WizError('SERVER_UNAVAILABLE', extractHost(url));
    }
    else if (isRequestError(error) && isAccessDeniedError(error)) {
        throw new Custom_error_1.default('NOT_LOGGED_IN', error.message);
    }
    else if (isUnauthorizedError(error)) {
        throw new Custom_error_1.default('UNAUTHORIZED', error.message);
    }
    else if (error.code && error.message) {
        throw new Custom_error_1.default(error.code, error.message);
    }
    throw error;
}
function isRequestError(error) {
    return error.response !== undefined;
}
function isAccessDeniedError(error) {
    var _a, _b;
    return ((_a = error.response) === null || _a === void 0 ? void 0 : _a.statusCode) === 403 && ((_b = error.response) === null || _b === void 0 ? void 0 : _b.body) === 'Access denied';
}
function extractHost(fullUrl) {
    const urlObj = url.parse(fullUrl);
    return url.format({
        protocol: urlObj.protocol,
        host: urlObj.host,
    });
}
function isInvalidUrlError(error) {
    return error.message && error.message.indexOf('Invalid URI') > -1 || error.code === 'ENOTFOUND';
}
function isServerError(error) {
    return error.code === 'SERVER_ERROR';
}
function isUnauthorizedError(error) {
    return error.code === 'ERR_NON_2XX_3XX_RESPONSE' &&
        error.message === 'Response code 401 (Unauthorized)';
}
//# sourceMappingURL=index.js.map