using Microsoft.Extensions.Configuration;
using ZB.MOM.WW.MxGateway.Server.Security.Tls;
using Xunit;

namespace ZB.MOM.WW.MxGateway.Tests.Security.Tls;

public sealed class KestrelTlsInspectorTests
{
    private static IConfiguration Config(params (string Key, string Value)[] entries)
        => new ConfigurationBuilder()
            .AddInMemoryCollection(entries.ToDictionary(e => e.Key, e => (string?)e.Value))
            .Build();

    /// <summary>An HTTPS endpoint with no certificate configured requires a generated certificate.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_True_WhenHttpsEndpointHasNoCertificate()
        => Assert.True(KestrelTlsInspector.RequiresGeneratedCertificate(
            Config(("Kestrel:Endpoints:Http:Url", "https://0.0.0.0:5120"))));

    /// <summary>When every configured endpoint is plaintext, no generated certificate is required.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_False_WhenAllEndpointsPlaintext()
        => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(
            Config(("Kestrel:Endpoints:Http:Url", "http://0.0.0.0:5120"))));

    /// <summary>An HTTPS endpoint with its own certificate path configured does not require a generated certificate.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_False_WhenHttpsEndpointHasOwnCertificate()
        => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(
            Config(
                ("Kestrel:Endpoints:Http:Url", "https://0.0.0.0:5120"),
                ("Kestrel:Endpoints:Http:Certificate:Path", @"C:\certs\real.pfx"))));

    /// <summary>With no endpoints configured at all, no generated certificate is required.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_False_WhenNoEndpointsConfigured()
        => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(Config()));

    /// <summary>An HTTPS endpoint configured with only a certificate thumbprint does not require a generated certificate.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_False_WhenHttpsEndpointHasThumbprintOnly()
        => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(
            Config(
                ("Kestrel:Endpoints:Https:Url", "https://0.0.0.0:5120"),
                ("Kestrel:Endpoints:Https:Certificate:Thumbprint", "AABBCCDDEEFF00112233445566778899AABBCCDD"))));

    /// <summary>An HTTPS endpoint configured with only a certificate subject does not require a generated certificate.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_False_WhenHttpsEndpointHasSubjectOnly()
        => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(
            Config(
                ("Kestrel:Endpoints:Https:Url", "https://0.0.0.0:5120"),
                ("Kestrel:Endpoints:Https:Certificate:Subject", "CN=myserver"))));

    /// <summary>An uppercase HTTPS URL scheme is still recognized as HTTPS and requires a generated certificate.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_True_WhenHttpsUrlIsUppercase()
        => Assert.True(KestrelTlsInspector.RequiresGeneratedCertificate(
            Config(("Kestrel:Endpoints:Https:Url", "HTTPS://0.0.0.0:5120"))));

    /// <summary>An HTTPS endpoint covered by the Kestrel default certificate does not require a generated certificate.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_False_WhenKestrelDefaultCertificateConfigured()
        => Assert.False(KestrelTlsInspector.RequiresGeneratedCertificate(
            Config(
                ("Kestrel:Endpoints:Https:Url", "https://0.0.0.0:5120"),
                ("Kestrel:Certificates:Default:Path", @"C:\certs\default.pfx"))));

    /// <summary>Among mixed endpoints, one HTTPS endpoint without a certificate still requires a generated certificate.</summary>
    [Fact]
    public void RequiresGeneratedCertificate_True_WhenMixedEndpointsAndOneHttpsHasNoCert()
        => Assert.True(KestrelTlsInspector.RequiresGeneratedCertificate(
            Config(
                ("Kestrel:Endpoints:Grpc:Url", "https://0.0.0.0:5120"),
                ("Kestrel:Endpoints:Grpc:Certificate:Thumbprint", "AABBCCDDEEFF00112233445566778899AABBCCDD"),
                ("Kestrel:Endpoints:Dashboard:Url", "https://0.0.0.0:5130"))));
}
