using Microsoft.Extensions.Configuration;

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

/// <summary>
/// Inspects the Kestrel configuration to decide whether the gateway must supply
/// a generated default certificate (an HTTPS endpoint exists with no certificate
/// of its own).
/// </summary>
public static class KestrelTlsInspector
{
    /// <summary>
    /// Returns <see langword="true"/> when at least one HTTPS endpoint in
    /// <c>Kestrel:Endpoints</c> has no certificate of its own (no
    /// <c>Certificate:Path</c>, <c>Certificate:Subject</c>, or
    /// <c>Certificate:Thumbprint</c>), meaning the gateway must supply a
    /// generated fallback certificate.
    /// </summary>
    /// <param name="configuration">The application configuration to inspect for Kestrel certificate settings.</param>
    /// <returns><see langword="true"/> if the gateway must supply a generated fallback certificate; otherwise <see langword="false"/>.</returns>
    public static bool RequiresGeneratedCertificate(IConfiguration configuration)
    {
        // A Kestrel default certificate applies to every endpoint that lacks its own.
        // If the operator configured one, the gateway must not override it.
        if (HasConfiguredCertificate(configuration.GetSection("Kestrel:Certificates:Default")))
        {
            return false;
        }

        IConfigurationSection endpoints = configuration.GetSection("Kestrel:Endpoints");
        foreach (IConfigurationSection endpoint in endpoints.GetChildren())
        {
            string? url = endpoint["Url"];
            if (string.IsNullOrWhiteSpace(url) ||
                !url.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
            {
                continue;
            }

            if (!HasConfiguredCertificate(endpoint.GetSection("Certificate")))
            {
                return true;
            }
        }

        return false;
    }

    private static bool HasConfiguredCertificate(IConfigurationSection certificate)
        => !string.IsNullOrWhiteSpace(certificate["Path"]) ||
           !string.IsNullOrWhiteSpace(certificate["Subject"]) ||
           !string.IsNullOrWhiteSpace(certificate["Thumbprint"]);
}
