"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClientBuilder = exports.extractErrorMessageFromAxiosError = void 0;
const axios_1 = __importDefault(require("axios"));
const logging_1 = require("../logging");
const extractErrorMessageFromAxiosError = (error) => {
    var _a, _b, _c, _d, _e, _f, _g;
    return (((_c = (_b = (_a = error === null || error === void 0 ? void 0 : 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) ||
        ((_e = (_d = error === null || error === void 0 ? void 0 : error.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.message) ||
        ((_g = (_f = error === null || error === void 0 ? void 0 : error.response) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.error) ||
        (error === null || error === void 0 ? void 0 : error.message) ||
        `${error}`);
};
exports.extractErrorMessageFromAxiosError = extractErrorMessageFromAxiosError;
class ClientBuilder {
    constructor() {
        this.commonHeaders = {};
        this._withRequestLogging = false;
        this._withResponseLogging = false;
    }
    static builder() {
        return new ClientBuilder();
    }
    withRequestLogging() {
        this._withRequestLogging = true;
        return this;
    }
    withResponseLogging() {
        this._withResponseLogging = true;
        return this;
    }
    setHeaders(headers) {
        this.commonHeaders = headers;
        return this;
    }
    setRemoteServiceName(serviceName) {
        this.remoteServiceName = serviceName;
        return this;
    }
    setBaseURL(baseURL) {
        this.baseURL = baseURL;
        return this;
    }
    buildDefault() {
        this.withRequestLogging();
        this.withResponseLogging();
        return this.build();
    }
    checkRequiredParams() {
        if (!this.baseURL) {
            throw new Error(`baseURL is required`);
        }
    }
    build() {
        this.checkRequiredParams();
        const client = axios_1.default.create({
            baseURL: this.baseURL,
            headers: Object.assign({ Accept: 'application/json', 'Content-Type': 'application/json' }, this.commonHeaders),
        });
        this.addRequestLogging(client);
        this.addResponseLogging(client);
        return client;
    }
    addResponseLogging(client) {
        if (!this._withResponseLogging) {
            return;
        }
        client.interceptors.response.use((response) => {
            logging_1.logger.info(`axios ${response.status} ${response.request.path}`, {
                payload: response.data,
            });
            return response;
        }, (error) => {
            // Could be NodeJS specific error and not an Axios one
            this.logAxiosError(error);
            return Promise.reject(error);
        });
    }
    logAxiosError(error) {
        var _a;
        if (!error.response) {
            logging_1.logger.error(`axios ${error.message}`);
            return;
        }
        let response = `axios ${(_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.status}`;
        const nestedError = (0, exports.extractErrorMessageFromAxiosError)(error);
        if (nestedError) {
            response = `${response} ${nestedError}`;
        }
        logging_1.logger.error(response, {
            payload: error.response.data,
        });
    }
    addRequestLogging(client) {
        if (!this._withRequestLogging) {
            return;
        }
        client.interceptors.request.use((request) => {
            var _a;
            logging_1.logger.info(`axios ${(_a = request.method) === null || _a === void 0 ? void 0 : _a.toUpperCase()} ${request.url}`, {
                payload: {
                    body: request.data,
                    baseURL: request.baseURL,
                },
            });
            return request;
        });
    }
}
exports.ClientBuilder = ClientBuilder;
//# sourceMappingURL=index.js.map