using Grpc.Net.Client;

namespace ZB.MOM.WW.Health;

/// <summary>
/// Options for <see cref="GrpcDependencyHealthCheck"/>.
/// </summary>
public sealed class GrpcDependencyOptions
{
    /// <summary>
    /// The reachability probe. Returns <c>true</c> when the dependency is reachable, <c>false</c>
    /// otherwise. When <c>null</c> the default probe is used: <see cref="GrpcChannel.ConnectAsync"/>,
    /// which drives the channel to the <see cref="Grpc.Core.ConnectivityState.Ready"/> state (or
    /// throws / cancels on failure). Override to perform a richer probe, e.g. a
    /// <c>grpc.health.v1.Health/Check</c> RPC returning <c>SERVING</c>.
    /// </summary>
    public Func<GrpcChannel, CancellationToken, Task<bool>>? Probe { get; set; }

    /// <summary>
    /// Human-readable name of the dependency, surfaced in the <c>HealthCheckResult</c> description.
    /// </summary>
    public string? DependencyName { get; set; }

    private TimeSpan _timeout = TimeSpan.FromSeconds(5);

    /// <summary>Maximum time the probe may take before it is treated as unreachable. Default 5 s.</summary>
    /// <exception cref="ArgumentOutOfRangeException">Thrown when set to a value &lt;= <see cref="TimeSpan.Zero"/>.</exception>
    public TimeSpan Timeout
    {
        get => _timeout;
        set
        {
            if (value <= TimeSpan.Zero)
            {
                throw new ArgumentOutOfRangeException(nameof(value), value, "Timeout must be greater than zero.");
            }

            _timeout = value;
        }
    }
}
