namespace ZB.MOM.WW.MxGateway.Client;

/// <summary>Configuration for automatic retry behavior on transient gRPC call failures.</summary>
public sealed class MxGatewayClientRetryOptions
{
    /// <summary>Gets the maximum number of attempts (initial + retries); default is 2.</summary>
    public int MaxAttempts { get; init; } = 2;

    /// <summary>Gets the initial delay between retry attempts; default is 200 milliseconds.</summary>
    public TimeSpan Delay { get; init; } = TimeSpan.FromMilliseconds(200);

    /// <summary>Gets the maximum delay between retry attempts; default is 2 seconds.</summary>
    public TimeSpan MaxDelay { get; init; } = TimeSpan.FromSeconds(2);

    /// <summary>Gets a value indicating whether to add randomness to retry delays; default is true.</summary>
    public bool UseJitter { get; init; } = true;

    /// <summary>Validates the retry options and throws if any constraint is violated.</summary>
    public void Validate()
    {
        if (MaxAttempts <= 0)
        {
            throw new ArgumentOutOfRangeException(
                nameof(MaxAttempts),
                "The retry max attempts value must be greater than zero.");
        }

        if (Delay <= TimeSpan.Zero)
        {
            throw new ArgumentOutOfRangeException(
                nameof(Delay),
                "The retry delay must be greater than zero.");
        }

        if (MaxDelay <= TimeSpan.Zero)
        {
            throw new ArgumentOutOfRangeException(
                nameof(MaxDelay),
                "The retry max delay must be greater than zero.");
        }

        if (MaxDelay < Delay)
        {
            throw new ArgumentOutOfRangeException(
                nameof(MaxDelay),
                "The retry max delay must be greater than or equal to the retry delay.");
        }
    }
}
