using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

namespace NATS.Server.Monitoring;

internal static class TlsPeerCertMapper
{
    public static TLSPeerCert[] FromCertificate(X509Certificate2? cert)
    {
        if (cert == null)
            return [];

        return
        [
            new TLSPeerCert
            {
                Subject = cert.Subject ?? string.Empty,
                SubjectPKISha256 = ComputeSubjectPkSha256(cert),
                CertSha256 = ComputeCertSha256(cert),
            },
        ];
    }

    public static TLSPeerCert[] FromClosedClient(ClosedClient closed)
    {
        if (string.IsNullOrEmpty(closed.TlsPeerCertSubject))
            return [];

        return
        [
            new TLSPeerCert
            {
                Subject = closed.TlsPeerCertSubject,
                SubjectPKISha256 = closed.TlsPeerCertSubjectPkSha256,
                CertSha256 = closed.TlsPeerCertSha256,
            },
        ];
    }

    public static (string Subject, string SubjectPkSha256, string CertSha256) ToClosedFields(X509Certificate2? cert)
    {
        if (cert == null)
            return (string.Empty, string.Empty, string.Empty);

        return (
            cert.Subject ?? string.Empty,
            ComputeSubjectPkSha256(cert),
            ComputeCertSha256(cert)
        );
    }

    private static string ComputeSubjectPkSha256(X509Certificate2 cert)
        => ToHexLower(SHA256.HashData(cert.GetPublicKey()));

    private static string ComputeCertSha256(X509Certificate2 cert)
        => ToHexLower(SHA256.HashData(cert.RawData));

    private static string ToHexLower(ReadOnlySpan<byte> bytes)
        => Convert.ToHexString(bytes).ToLowerInvariant();
}
