"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EndpointDiscoveryRetryPolicy = void 0;
const index_js_1 = require("../common/index.js");
const helper_js_1 = require("../common/helper.js");
/**
 * This class implements the retry policy for endpoint discovery.
 * @hidden
 */
class EndpointDiscoveryRetryPolicy {
    globalEndpointManager;
    resourceType;
    operationType;
    globalPartitionEndpointManager;
    /** Current retry attempt count. */
    currentRetryAttemptCount;
    /** Retry interval in milliseconds. */
    retryAfterInMs;
    /** Max number of retry attempts to perform. */
    maxTries;
    static maxTries = 120; // TODO: Constant?
    static retryAfterInMs = 1000;
    /**
     * @param globalEndpointManager - The GlobalEndpointManager instance.
     */
    constructor(globalEndpointManager, resourceType, operationType, globalPartitionEndpointManager) {
        this.globalEndpointManager = globalEndpointManager;
        this.resourceType = resourceType;
        this.operationType = operationType;
        this.globalPartitionEndpointManager = globalPartitionEndpointManager;
        this.maxTries = EndpointDiscoveryRetryPolicy.maxTries;
        this.currentRetryAttemptCount = 0;
        this.retryAfterInMs = EndpointDiscoveryRetryPolicy.retryAfterInMs;
    }
    /**
     * Determines whether the request should be retried or not.
     * @param err - Error returned by the request.
     */
    async shouldRetry(err, diagnosticNode, retryContext, locationEndpoint, requestContext) {
        if (!err) {
            return false;
        }
        if (!retryContext || !locationEndpoint) {
            return false;
        }
        if (!this.globalEndpointManager.enableEndpointDiscovery) {
            return false;
        }
        if (this.globalPartitionEndpointManager) {
            const didFailover = await this.globalPartitionEndpointManager.tryPartitionLevelFailover(requestContext, diagnosticNode);
            if (didFailover) {
                return true;
            }
        }
        if (this.currentRetryAttemptCount >= this.maxTries) {
            return false;
        }
        this.currentRetryAttemptCount++;
        retryContext.retryCount = this.currentRetryAttemptCount;
        retryContext.clearSessionTokenNotAvailable = false;
        retryContext.retryRequestOnPreferredLocations = false;
        diagnosticNode.addData({ successfulRetryPolicy: "endpointDiscovery" });
        // check if this is a readDatabaseAccount call
        // If yes, then simply return true (avoid recursive call triggered for readDatabaseAccount)
        if (this.resourceType === index_js_1.ResourceType.none && this.operationType === index_js_1.OperationType.Read) {
            return true;
        }
        if ((0, helper_js_1.isReadRequest)(this.operationType)) {
            await this.globalEndpointManager.markCurrentLocationUnavailableForRead(diagnosticNode, locationEndpoint);
        }
        else {
            await this.globalEndpointManager.markCurrentLocationUnavailableForWrite(diagnosticNode, locationEndpoint);
        }
        return true;
    }
}
exports.EndpointDiscoveryRetryPolicy = EndpointDiscoveryRetryPolicy;
//# sourceMappingURL=endpointDiscoveryRetryPolicy.js.map