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());
    });
};
import * as logger from "../logger";
import { GetBridFromChainException } from "./errors";
import handleRequest from "./httpUtil";
export function getBrid(urlBase, chainId) {
    if (chainId >= 0) {
        const url = `${urlBase}/brid/iid_${chainId}`;
        return fetch(url).then((response) => {
            if (response.ok)
                return response.text();
            throw new GetBridFromChainException(chainId, response.statusText);
        });
    }
    else {
        const url = `${urlBase}/_debug`;
        return fetch(url).then((response) => {
            if (response.ok)
                return response
                    .json()
                    .then((json) => json.blockchain[json.blockchain.length - 1].brid);
            throw new GetBridFromChainException(chainId, response.statusText);
        });
    }
}
export function requestWithRetry(method, path, config, postObject) {
    return __awaiter(this, void 0, void 0, function* () {
        let statusCode, rspBody, error;
        const noRetryStatusCodes = [200, 400, 409, 500];
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        for (const _endpoint of config.endpointPool) {
            const endpoint = nextEndpoint(config.endpointPool);
            for (let attempt = 0; attempt < config.attemptsPerEndpoint; attempt++) {
                ({ error, statusCode, rspBody } = yield handleRequest(method, path, endpoint, postObject));
                if (noRetryStatusCodes.includes(statusCode)) {
                    return { error, statusCode, rspBody };
                }
                if (statusCode == 503) {
                    break;
                }
                logger.info(`${method} request failed on ${endpoint}. Attempt: ${attempt + 1} / ${config.attemptsPerEndpoint}`);
                yield sleep(config.attemptInterval);
            }
        }
        return { error, statusCode, rspBody };
    });
}
export function nextEndpoint(endpointPool) {
    return endpointPool[Math.floor(Math.random() * endpointPool.length)];
}
export const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
export function convertToPrintable(responseObject) {
    if (typeof responseObject === "bigint") {
        return responseObject + "n";
    }
    else if (typeof responseObject === "object") {
        return JSON.stringify(responseObject, (key, value) => typeof value === "bigint" ? value + "n" : value);
    }
    else {
        return responseObject;
    }
}
//# sourceMappingURL=restclientutil.js.map