"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProviderHealth = void 0;
const logger_1 = __importDefault(require("../../../logger"));
const DEFAULTS = {
    failureThreshold: 5,
    cooldownMs: 60000
};
/**
 * Tracks consecutive failures per provider and skips unhealthy providers
 * until a cooldown period elapses.
 */
class ProviderHealth {
    constructor(providerName, config, keyParts) {
        this.consecutiveFailures = 0;
        this.lastFailureTime = 0;
        this.config = { ...DEFAULTS, ...config };
        this.key = keyParts
            ? `${keyParts.chain}:${keyParts.network}:${providerName}`
            : providerName;
    }
    /** Can we send a request to this provider? */
    isAvailable() {
        if (this.consecutiveFailures < this.config.failureThreshold)
            return true;
        // Over threshold — check if cooldown has elapsed
        const elapsed = Date.now() - this.lastFailureTime;
        if (elapsed >= this.config.cooldownMs) {
            // Cooldown elapsed — allow one retry (reset failures so it gets one shot)
            logger_1.default.info(`ProviderHealth [${this.key}]: cooldown elapsed, retrying`);
            this.consecutiveFailures = this.config.failureThreshold - 1;
            return true;
        }
        return false;
    }
    recordSuccess() {
        if (this.consecutiveFailures > 0) {
            logger_1.default.info(`ProviderHealth [${this.key}]: recovered after ${this.consecutiveFailures} failures`);
        }
        this.consecutiveFailures = 0;
    }
    recordFailure(error) {
        this.consecutiveFailures++;
        this.lastFailureTime = Date.now();
        if (this.consecutiveFailures >= this.config.failureThreshold) {
            logger_1.default.warn(`ProviderHealth [${this.key}]: skipping provider (${this.consecutiveFailures} consecutive failures, ` +
                `cooldown ${this.config.cooldownMs}ms, last error: ${error.message})`);
        }
    }
    getStatus() {
        return {
            available: this.isAvailable(),
            consecutiveFailures: this.consecutiveFailures
        };
    }
}
exports.ProviderHealth = ProviderHealth;
//# sourceMappingURL=providerHealth.js.map