using System.Security.Cryptography.X509Certificates;
using InABox.Core;
using WebSocketSharp;
using WebSocketSharp.Server;

namespace InABox.Rpc
{
    public class RpcServerSocketTransport : RpcServerTransport<RpcServerSocketConnection>
    {
        private WebSocketServer? _server;

        public static X509Certificate2? Certificate { get; set; }
        
        //public static void InitCertificate(string certificateFile) => Certificate = new X509Certificate2(certificateFile);
        
        public override bool IsSecure() => Certificate != null;
        
        public RpcServerSocketTransport(int port, string? certificatefile = null) 
        {
            if (File.Exists(certificatefile))
            {
                try
                {
                    var certificate = new X509Certificate2(certificatefile);
                    if (certificate.NotAfter > DateTime.Now)
                        Certificate = certificate;
                }
                catch
                {
                }
            }
            
            _server = new WebSocketServer(port, Certificate != null);
            _server.SslConfiguration.ServerCertificate = Certificate;
            _server?.AddWebSocketService("/", () => new RpcServerSocketConnection() { Transport = this } );
        }
        
        public override void Start()
        {
            _server?.Start();
        }

        public override void Send(RpcServerSocketConnection connection, RpcMessage message)
        {
            connection.Send(message);
        }

        public override void Stop()
        {
            _server?.Stop();
        }

        public void ConnectionOpened(RpcServerSocketConnection connection) 
            => DoOpen(connection);

        public void ConnectionException(RpcServerSocketConnection connection, Exception e) 
            => DoException(connection, e);

        public void ConnectionClosed(RpcServerSocketConnection connection, CloseEventArgs e)
            => DoClose(connection, (e.Code == 1000) ? RpcTransportCloseEventType.Closed : RpcTransportCloseEventType.Error);
        
    }
}