using System.Net.Http;
using System.Net.Security;
using ZB.MOM.WW.MxGateway.Client;

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

public sealed class MxGatewayClientTlsHandlerTests
{
    /// <summary>
    /// Verifies that when TLS is used with no pinned CA and RequireCertificateValidation is false (default),
    /// the handler installs an accept-all callback so the gateway's self-signed cert is trusted.
    /// The callback must return true regardless of chain errors.
    /// </summary>
    [Fact]
    public void Handler_SkipsVerification_WhenTlsAndNoCaPinned()
    {
        MxGatewayClientOptions options = new()
        {
            Endpoint = new Uri("https://localhost:5120"),
            ApiKey = "k",
            UseTls = true,
        };
        using SocketsHttpHandler handler = MxGatewayClient.CreateHttpHandlerForTests(options);
        Assert.NotNull(handler.SslOptions.RemoteCertificateValidationCallback);
        Assert.True(handler.SslOptions.RemoteCertificateValidationCallback!(null!, null!, null, SslPolicyErrors.RemoteCertificateChainErrors));
    }

    /// <summary>
    /// Verifies that when RequireCertificateValidation is true, the callback is left null
    /// so the OS trust store performs validation.
    /// </summary>
    [Fact]
    public void Handler_KeepsDefaultVerification_WhenRequireCertificateValidation()
    {
        MxGatewayClientOptions options = new()
        {
            Endpoint = new Uri("https://localhost:5120"),
            ApiKey = "k",
            UseTls = true,
            RequireCertificateValidation = true,
        };
        using SocketsHttpHandler handler = MxGatewayClient.CreateHttpHandlerForTests(options);
        Assert.Null(handler.SslOptions.RemoteCertificateValidationCallback);
    }
}

public sealed class GalaxyRepositoryClientTlsHandlerTests
{
    /// <summary>
    /// Verifies that when TLS is used with no pinned CA and RequireCertificateValidation is false (default),
    /// the Galaxy client handler installs an accept-all callback so the gateway's self-signed cert is trusted.
    /// The callback must return true regardless of chain errors.
    /// </summary>
    [Fact]
    public void Handler_SkipsVerification_WhenTlsAndNoCaPinned()
    {
        MxGatewayClientOptions options = new()
        {
            Endpoint = new Uri("https://localhost:5120"),
            ApiKey = "k",
            UseTls = true,
        };
        using SocketsHttpHandler handler = GalaxyRepositoryClient.CreateHttpHandlerForTests(options);
        Assert.NotNull(handler.SslOptions.RemoteCertificateValidationCallback);
        Assert.True(handler.SslOptions.RemoteCertificateValidationCallback!(null!, null!, null, SslPolicyErrors.RemoteCertificateChainErrors));
    }

    /// <summary>
    /// Verifies that when RequireCertificateValidation is true, the Galaxy client callback is left null
    /// so the OS trust store performs validation.
    /// </summary>
    [Fact]
    public void Handler_KeepsDefaultVerification_WhenRequireCertificateValidation()
    {
        MxGatewayClientOptions options = new()
        {
            Endpoint = new Uri("https://localhost:5120"),
            ApiKey = "k",
            UseTls = true,
            RequireCertificateValidation = true,
        };
        using SocketsHttpHandler handler = GalaxyRepositoryClient.CreateHttpHandlerForTests(options);
        Assert.Null(handler.SslOptions.RemoteCertificateValidationCallback);
    }
}
