using Xunit;

namespace ZB.MOM.WW.LmxProxy.Client.Tests;

public class LmxProxyClientBuilderTests
{
    [Fact]
    public void Build_ThrowsWhenHostNotSet()
    {
        var builder = new LmxProxyClientBuilder();
        Assert.Throws<InvalidOperationException>(() => builder.Build());
    }

    [Fact]
    public void Build_DefaultPort_Is50051()
    {
        var client = new LmxProxyClientBuilder()
            .WithHost("localhost")
            .Build();
        Assert.NotNull(client);
    }

    [Fact]
    public void WithPort_ThrowsOnZero()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() =>
            new LmxProxyClientBuilder().WithPort(0));
    }

    [Fact]
    public void WithPort_ThrowsOn65536()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() =>
            new LmxProxyClientBuilder().WithPort(65536));
    }

    [Fact]
    public void WithTimeout_ThrowsOnNegative()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() =>
            new LmxProxyClientBuilder().WithTimeout(TimeSpan.FromSeconds(-1)));
    }

    [Fact]
    public void WithTimeout_ThrowsOver10Minutes()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() =>
            new LmxProxyClientBuilder().WithTimeout(TimeSpan.FromMinutes(11)));
    }

    [Fact]
    public void WithRetryPolicy_ThrowsOnZeroAttempts()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() =>
            new LmxProxyClientBuilder().WithRetryPolicy(0, TimeSpan.FromSeconds(1)));
    }

    [Fact]
    public void WithRetryPolicy_ThrowsOnZeroDelay()
    {
        Assert.Throws<ArgumentOutOfRangeException>(() =>
            new LmxProxyClientBuilder().WithRetryPolicy(3, TimeSpan.Zero));
    }

    [Fact]
    public void Build_WithAllOptions_Succeeds()
    {
        var client = new LmxProxyClientBuilder()
            .WithHost("10.100.0.48")
            .WithPort(50051)
            .WithApiKey("test-key")
            .WithTimeout(TimeSpan.FromSeconds(15))
            .WithRetryPolicy(5, TimeSpan.FromSeconds(2))
            .WithMetrics()
            .WithCorrelationIdHeader("X-Correlation-ID")
            .Build();
        Assert.NotNull(client);
    }

    [Fact]
    public void Build_WithTls_ValidatesCertificatePaths()
    {
        var builder = new LmxProxyClientBuilder()
            .WithHost("localhost")
            .WithTlsConfiguration(new ClientTlsConfiguration
            {
                UseTls = true,
                ServerCaCertificatePath = "/nonexistent/cert.pem"
            });
        Assert.Throws<FileNotFoundException>(() => builder.Build());
    }

    [Fact]
    public void WithHost_ThrowsOnNull()
    {
        Assert.Throws<ArgumentException>(() =>
            new LmxProxyClientBuilder().WithHost(null!));
    }

    [Fact]
    public void WithHost_ThrowsOnEmpty()
    {
        Assert.Throws<ArgumentException>(() =>
            new LmxProxyClientBuilder().WithHost(""));
    }
}
