using IceCoffee.FastSocket.Tcp;
using langguanApi.Model.Dto;
using langguanApi.Model;
using langguanApi.Service.HJ212;
using System.Net.Sockets;
using System.Net;
using System.Text;
using JT808.Protocol;
using Org.BouncyCastle.Utilities;
using LogicExtensions;
using JT808.Protocol.Enums;
using JT808.Protocol.MessageBody;
namespace langguanApi.Service
{
    public class Gps808SocketServer
    {
        /// 
        /// 缓冲器
        /// 
        private byte[] result = new byte[1024];
        /// 
        /// 最大连接数
        /// 
        private int maxClientCount;
        /// 
        /// 服务IP地址
        /// 
        private string ip;
        /// 
        /// 服务端口号
        /// 
        private int port => 5002;
        // 编码
        // private string code;
        /// 
        /// 客户端列表
        /// 
        private List ClientSockets;
        /// 
        /// IP终端
        /// 
        private IPEndPoint ipEndPoint;
        /// 
        /// 服务端Socket 
        /// 
        private Socket ServerSocket;
        private static NetServer server;
        private static IceCoffee.FastSocket.Tcp.TcpClient client;
        /// 
        /// 启动服务
        /// 
        /// 
        public async Task Start()
        {
            ip = IPAddress.Any.ToString();
            server = new NetServer(ip, port);
            server.Started += OnNetServer_Started;
            server.ExceptionCaught += OnNetServer_ExceptionCaught;
            server.SessionStarted += OnNetServer_SessionStarted;
            server.SessionClosed += OnNetServer_SessionClosed;
            server.ReceivedData += OnNetServer_ReceivedData;
            server.SendData += OnNetServer_SendData;
            server.Start();
        }
        private void OnNetServer_Started()
        {
            Console.WriteLine($"开始监听gps: {ip}:{port}");
        }
        private void OnNetServer_SendData(NetSession session, NetPackage netPackage, string rawText)
        {
            Console.WriteLine($"发送给gps: {session.RemoteIPEndPoint}: {rawText}");
        }
        private void OnNetServer_SessionClosed(TcpSession session)
        {
            Console.WriteLine("会话关闭gps: " + session.RemoteIPEndPoint + ", 当前会话总数: " + server.SessionCount);
        }
        private static void OnNetServer_SessionStarted(TcpSession session)
        {
            Console.WriteLine("会话开始gps: " + session.RemoteIPEndPoint + ", 当前会话总数: " + server.SessionCount);
        }
        private async void OnNetServer_ReceivedData(TcpSession session, NetPackage netPackage, string rawText)
        {
            Console.WriteLine("收到自gps: " + session.RemoteIPEndPoint + ": " + rawText);
            byte[] bytes = rawText.ToBytes();
            //2.将数组反序列化
            //   var jT808Package =new JT808Serializer.Deserialize(bytes.AsSpan());
            //3.解析数据
            var jT808Package = new JT808Serializer().Deserialize(bytes);
            //4.数据包体
            JT808_0x0200 jT808_0x0200 = (JT808_0x0200)jT808Package.Bodies;
            var lon = jT808_0x0200.Lat;
            var lat= jT808_0x0200.Lng;
            Console.WriteLine("经度:" + lon + " 纬度:" + lat);
            //4.处理数据
            //5.返回数据
            //6.发送数据
            // st 27 =voc,st=31 cems, st=32,tsp, st=22 微站
        }
        private void OnNetServer_ExceptionCaught(Exception ex)
        {
            Console.WriteLine("Error in NetServer gps" + ex);
        }
        byte[] CallCRC(byte[] data)
        {
            string ccc = Convert.ToString(getCrc(data), 16).PadLeft(4, '0');
            return Encoding.ASCII.GetBytes(ccc.ToUpper());
        }
        private int getCrc(byte[] data)
        {
            int high;
            int flag;
            // 16位寄存器,所有数位均为1
            int wcrc = 0xffff;
            for (int i = 0; i < data.Length; i++)
            {
                // 16 位寄存器的高位字节
                high = wcrc >> 8;
                // 取被校验串的一个字节与 16 位寄存器的高位字节进行“异或”运算
                wcrc = high ^ data[i];
                for (int j = 0; j < 8; j++)
                {
                    flag = wcrc & 0x0001;
                    // 把这个 16 寄存器向右移一位
                    wcrc = wcrc >> 1;
                    // 若向右(标记位)移出的数位是 1,则生成多项式 1010 0000 0000 0001 和这个寄存器进行“异或”运算
                    if (flag == 1)
                        wcrc ^= 0xa001;
                }
            }
            return wcrc;
        }
    }
}