"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.get = get;
exports.post = post;
exports.setLogger = setLogger;
const url_1 = require("url");
const logger_1 = require("../logger");
const lib_types_1 = require("@shardeum-foundation/lib-types");
const utils_1 = require("../utils");
const customHttpFunctions_1 = require("../http/customHttpFunctions");
let _logger = null;
let getIndex = 1;
let postIndex = -1;
const httpResLogLength = 5000;
function _containsProtocol(url) {
    if (!url.match('https?://*'))
        return false;
    return true;
}
function _normalizeUrl(url) {
    let normalized = url;
    if (!_containsProtocol(url))
        normalized = 'http://' + url;
    return normalized;
}
async function _get(host, logIndex, timeout = 1000) {
    try {
        const res = await (0, customHttpFunctions_1.customGot)().get(host.href, {
            timeout: timeout, //  Omar - setting this to 1 sec
            retry: 0, // Omar - setting this to 0.
            headers: {
                Accept: 'application/json',
            },
        });
        // Explicitly parse the response body as JSON if it's not already parsed
        let responseBody = res.body;
        if (typeof responseBody === 'string' && res.headers['content-type']?.includes('application/json')) {
            try {
                responseBody = lib_types_1.Utils.safeJsonParse(responseBody);
            }
            catch (parseError) {
                console.error('Failed to parse JSON response:', parseError);
            }
        }
        return { ...res, body: responseBody };
    }
    catch (error) {
        if (logger_1.logFlags.playback === false && logger_1.logFlags.verbose === false) {
            throw error;
        }
        // log and then throw error
        logError('post', error, host, logIndex);
    }
}
/*
  Queries the given host for a JSON payload
  Returns a promise, resolves parsed JSON response
*/
async function get(url, getResponseObj = false, timeout = 1000) {
    let normalized = _normalizeUrl(url);
    let host = (0, url_1.parse)(normalized, true);
    getIndex++;
    const localIndex = getIndex;
    if (_logger) {
        /* prettier-ignore */ if (logger_1.logFlags.playback)
            _logger.playbackLog('self', host.hostname + ':' + host.port, 'HttpRequest', host.pathname, localIndex, '');
    }
    let res = await _get(host, localIndex, timeout);
    if (_logger) {
        /* prettier-ignore */ if (logger_1.logFlags.playback)
            _logger.playbackLog(host.hostname + ':' + host.port, 'self', 'HttpResponseRecv', host.pathname, localIndex, (0, utils_1.stringifyReduceLimit)(res.body, 1000) + '  res:: ' + (0, utils_1.stringifyReduceLimit)(res, httpResLogLength));
    }
    if (getResponseObj) {
        //@ts-ignore
        return res;
    }
    return res.body;
}
async function _post(host, payload, logIndex, timeout = 1000) {
    try {
        const res = await (0, customHttpFunctions_1.customGot)().post(host.href, {
            timeout: timeout, // Omar - set this to 1 sec
            retry: 0, // Omar - set this to 0
            headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json',
            },
            body: lib_types_1.Utils.safeStringify(payload),
        });
        //if (getResponseObj) return res
        //return res.body
        // Explicitly parse the response body as JSON if it's not already parsed
        let responseBody = res.body;
        if (typeof responseBody === 'string' && res.headers['content-type']?.includes('application/json')) {
            try {
                responseBody = lib_types_1.Utils.safeJsonParse(responseBody);
            }
            catch (parseError) {
                console.error('Failed to parse JSON response:', parseError);
            }
        }
        return { ...res, body: responseBody };
    }
    catch (error) {
        if (logger_1.logFlags.playback === false && logger_1.logFlags.verbose === false) {
            throw error;
        }
        // log and then throw error
        logError('post', error, host, logIndex);
    }
}
/*
  Posts a JSON payload to a given host
  Returns a promise, resolves parsed JSON response if successful, rejects on error
*/
async function post(givenHost, body, getResponseObj = false, timeout = 1000) {
    let normalized = _normalizeUrl(givenHost);
    let host = (0, url_1.parse)(normalized, true);
    postIndex--;
    const localIndex = postIndex;
    if (_logger) {
        /* prettier-ignore */ if (logger_1.logFlags.playback)
            _logger.playbackLog('self', host.hostname + ':' + host.port, 'HttpRequest', host.pathname, localIndex, body);
    }
    let res = await _post(host, body, localIndex, timeout);
    if (_logger) {
        /* prettier-ignore */ if (logger_1.logFlags.playback)
            _logger.playbackLog(host.hostname + ':' + host.port, 'self', 'HttpResponseRecv', host.pathname, localIndex, (0, utils_1.stringifyReduceLimit)(res.body, 1000) + '  res:: ' + (0, utils_1.stringifyReduceLimit)(res, httpResLogLength));
    }
    if (getResponseObj)
        return res;
    return res.body;
}
function logError(method, error, host, logIndex) {
    if (error.code === 'ETIMEDOUT') {
        /* prettier-ignore */ if (logger_1.logFlags.verbose)
            console.error(`${method}: HTTP request timed out:`, error);
        if (_logger) {
            /* prettier-ignore */ if (logger_1.logFlags.playback)
                _logger.playbackLog(host.hostname + ':' + host.port, 'self', 'HttpResponseRecv-timeout', host.pathname, logIndex, lib_types_1.Utils.safeStringify(error));
        }
        throw error;
    }
    else if (error.response && error.response.statusCode === 400) {
        /* prettier-ignore */ if (logger_1.logFlags.verbose)
            console.error(`${method}: Bad Request:`, error.message, ' ', error);
        if (_logger) {
            /* prettier-ignore */ if (logger_1.logFlags.playback)
                _logger.playbackLog(host.hostname + ':' + host.port, 'self', 'HttpResponseRecv-400', host.pathname, logIndex, lib_types_1.Utils.safeStringify(error));
        }
        throw error;
    }
    else {
        // Handle other errors
        /* prettier-ignore */ if (logger_1.logFlags.verbose)
            console.error(`${method}: An unexpected error occurred:`, error);
        if (_logger) {
            /* prettier-ignore */ if (logger_1.logFlags.playback)
                _logger.playbackLog(host.hostname + ':' + host.port, 'self', 'HttpResponseRecv-err', host.pathname, logIndex, lib_types_1.Utils.safeStringify(error));
        }
        throw error;
    }
}
function buildGotErrorDescription(error) {
    let description = 'Got error: ';
    // Check if the error has a code and include it in the description
    if (error.code) {
        description += `[Code: ${error.code}] `;
    }
    // Check if the error has a response and statusCode
    if (error.response && error.response.statusCode) {
        description += `[Status Code: ${error.response.statusCode}] `;
    }
    // Check if the error has a message and include it
    if (error.message) {
        description += error.message;
    }
    return description;
}
function setLogger(logger) {
    _logger = logger;
}
//# sourceMappingURL=index.js.map