using System.IO;
using Grpc.Core;
using Serilog;
using ZB.MOM.WW.LmxProxy.Host.Configuration;

namespace ZB.MOM.WW.LmxProxy.Host.Security
{
    /// <summary>
    ///     Manages TLS certificates for the gRPC server.
    ///     If TLS is enabled but certs are missing, logs a warning (self-signed generation
    ///     would be added as a future enhancement, or done manually).
    /// </summary>
    public static class TlsCertificateManager
    {
        private static readonly ILogger Log = Serilog.Log.ForContext(typeof(TlsCertificateManager));

        /// <summary>
        ///     Creates gRPC server credentials based on TLS configuration.
        ///     Returns InsecureServerCredentials if TLS is disabled.
        /// </summary>
        public static ServerCredentials CreateServerCredentials(TlsConfiguration config)
        {
            if (!config.Enabled)
            {
                Log.Information("TLS disabled, using insecure server credentials");
                return ServerCredentials.Insecure;
            }

            if (!File.Exists(config.ServerCertificatePath) || !File.Exists(config.ServerKeyPath))
            {
                Log.Warning("TLS enabled but certificate files not found. Falling back to insecure credentials. " +
                    "Cert: {CertPath}, Key: {KeyPath}",
                    config.ServerCertificatePath, config.ServerKeyPath);
                return ServerCredentials.Insecure;
            }

            var certChain = File.ReadAllText(config.ServerCertificatePath);
            var privateKey = File.ReadAllText(config.ServerKeyPath);

            var keyCertPair = new KeyCertificatePair(certChain, privateKey);

            if (config.RequireClientCertificate && File.Exists(config.ClientCaCertificatePath))
            {
                var caCert = File.ReadAllText(config.ClientCaCertificatePath);
                Log.Information("TLS enabled with mutual TLS (client certificate required)");
                return new SslServerCredentials(
                    new[] { keyCertPair },
                    caCert,
                    SslClientCertificateRequestType.RequestAndRequireAndVerify);
            }

            Log.Information("TLS enabled (server-only)");
            return new SslServerCredentials(new[] { keyCertPair });
        }
    }
}
