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 { logger } from "../..";
import handleRequest from "./httpUtil";
import { nextEndpoint, sleep } from "./restclientutil";
const clientErrors = [400, 404, 409, 413];
const serverErrors = [500, 503];
export function abortOnError({ method, path, config, postObject, }) {
    return __awaiter(this, void 0, void 0, function* () {
        return yield retryRequest({ method, path, config, postObject }, serverErrors);
    });
}
export function tryNextOnError({ method, path, config, postObject, }) {
    return __awaiter(this, void 0, void 0, function* () {
        return yield retryRequest({ method, path, config, postObject }, serverErrors.concat(clientErrors));
    });
}
export function singleEndpoint({ method, path, config, postObject, }) {
    return __awaiter(this, void 0, void 0, function* () {
        let statusCode, rspBody, error;
        const errorCodes = serverErrors.concat(clientErrors);
        for (let attempt = 0; attempt < config.attemptsPerEndpoint; attempt++) {
            ({ error, statusCode, rspBody } = yield handleRequest(method, path, nextEndpoint(config.endpointPool), postObject));
            if (!errorCodes.includes(statusCode) && !error) {
                return { error, statusCode, rspBody };
            }
            logger.info(`${method} request failed on ${config.endpointPool[0]}. Attempt: ${attempt + 1} / ${config.attemptsPerEndpoint}`);
            yield sleep(config.attemptInterval);
        }
        return { error, statusCode, rspBody };
    });
}
export function retryRequest({ method, path, config, postObject }, errorCodes) {
    return __awaiter(this, void 0, void 0, function* () {
        let statusCode, rspBody, error;
        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 (!errorCodes.includes(statusCode) && !error) {
                    return { error, statusCode, rspBody };
                }
                logger.info(`${method} request failed on ${endpoint}. Attempt: ${attempt + 1} / ${config.attemptsPerEndpoint}`);
                yield sleep(config.attemptInterval);
            }
        }
        return { error, statusCode, rspBody };
    });
}
//# sourceMappingURL=failoverStrategies.js.map