using System.Net.Sockets;
using System.Net;
using System.Text;
using IceCoffee.FastSocket.Tcp;
using langguanApi.Model.Dto;
using Newtonsoft.Json;
using langguanApi.Model;
using langguanApi.Service.HJ212;
using langguanApi.Extensions.AutoDI;
namespace langguanApi.Service
{
    public class HJ212SocketServer
    {
        private Hj212Service _hj212Service;
        private DeviceService _deviceService;
        public HJ212SocketServer(Hj212Service hj212Service, DeviceService deviceService)
        {
            _hj212Service = hj212Service;
            _deviceService = deviceService;
        }
        /// 
        /// 缓冲器
        /// 
        private byte[] result = new byte[1024];
        /// 
        /// 最大连接数
        /// 
        private int maxClientCount;
        /// 
        /// 服务IP地址
        /// 
        private string ip;
        /// 
        /// 服务端口号
        /// 
        private int port => 5001;
        // 编码
        // 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($"开始监听: {ip}:{port}");
        }
        private void OnNetServer_SendData(NetSession session, NetPackage netPackage, string rawText)
        {
            Console.WriteLine($"发送给: {session.RemoteIPEndPoint}: {rawText}");
        }
        private void OnNetServer_SessionClosed(TcpSession session)
        {
            Console.WriteLine("会话关闭: " + session.RemoteIPEndPoint + ", 当前会话总数: " + server.SessionCount);
        }
        private static void OnNetServer_SessionStarted(TcpSession session)
        {
            Console.WriteLine("会话开始: " + session.RemoteIPEndPoint + ", 当前会话总数: " + server.SessionCount);
        }
        private async void OnNetServer_ReceivedData(TcpSession session, NetPackage netPackage, string rawText)
        {
            Console.WriteLine("收到自: " + session.RemoteIPEndPoint + ": " + rawText);
            HJ212_2017 hj = new HJ212_2017();
            // st 27 =voc,st=31 cems, st=32,tsp
            if (hj.DecodeData(rawText))
            {
                var body = JsonConvert.SerializeObject(hj.CP);
                var entity = JsonConvert.DeserializeObject(body);
                entity.deviceMN = hj.DATA_HEAD["MN"];
                await _deviceService.Add(new DeviceAddDto
                {
                    deviceMN = hj.DATA_HEAD["MN"],
                    DeviceType = SetDeviceType(hj.DATA_HEAD["ST"]),
                    Ip= session.RemoteIPEndPoint.ToString(),
                });
                //校验通过,开始入库
                await _hj212Service.Add(entity, session.RemoteIPEndPoint.ToString());
            }
        }
        private int SetDeviceType(string st)
        {
            //st 27 =voc,st=31 cems, st=32,tsp
            //1 voc,2 cems,3,tsp,4 video
            switch (st)
            {
                case "27": return 1;
                case "31": return 2;
                case "32": return 3;
                case "33": return 4;
            }
            return 0;
        }
        private void OnNetServer_ExceptionCaught(Exception ex)
        {
            Console.WriteLine("Error in NetServer" + 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;
        }
    }
}