using IceCoffee.FastSocket.Tcp;
using IceCoffee.HJ212;
using IceCoffee.HJ212.Models;
using LangGuan.Command.Model;
using LangGuan.Command.Model.EntityModel;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace LangGuan.Services
{
    /// 
    /// 启动socket
    /// 
    public class HJ212SocketServer
    {
        private Hj212Service _hj212Service;
        private DeviceSerive _deviceSerive;
        /// 
        /// 
        /// 
        /// 
        /// 
        public HJ212SocketServer(Hj212Service hj212Service, DeviceSerive deviceSerive)
        {
            _hj212Service = hj212Service;
            _deviceSerive = deviceSerive;
        }
        /// 
        /// 缓冲器
        /// 
        private byte[] result = new byte[1024];
        /// 
        /// 最大连接数
        /// 
        private int maxClientCount;
        /// 
        /// 服务IP地址
        /// 
        private string ip;
        /// 
        /// 服务端口号
        /// 
        private int port => 9001;
        // 编码
        // 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();
            //client = new IceCoffee.FastSocket.Tcp.TcpClient(ip, port);
            //client.ConnectAsync();
            //client.Connected += OnClient_Connected;
            //try
            //{
            //    ip = IPAddress.Any.ToString();
            //    maxClientCount = 256; //设定最大连接数
            //    ClientSockets = new List();
            //    ipEndPoint = new IPEndPoint(IPAddress.Any, port);      //初始化IP终端 
            //    ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);        //初始化服务端Socket 
            //    ServerSocket.Bind(this.ipEndPoint);      //端口绑定
            //    ServerSocket.Listen(100);     //设置监听数目 
            //    Console.WriteLine($"socket服务已经启动端口:{port}");
            //    var handler = await ServerSocket.AcceptAsync();
            //    string data = null;
            //    byte[] bytes = null;
            //    while (true)
            //    {
            //        bytes = new byte[1024];
            //        int bytesRec = handler.Receive(bytes);
            //        data = Encoding.UTF8.GetString(bytes, 0, bytesRec);
            //        Console.WriteLine($"客户端发来数据:{data}");
            //        if (data.IndexOf("/r/n") > -1)
            //        {
            //            break;
            //        }
            //    }
            //    Console.WriteLine($"客户端发来数据:{data}");
            //    handler.Send(PackData("1"));
            //    handler.Shutdown(SocketShutdown.Both);
            //    handler.Close();
            //    //while (true)
            //    //{
            //    //    if (handler.Connected)
            //    //    {
            //    //        var buffer = new byte[1_024];
            //    //        var received = await handler.ReceiveAsync(buffer, SocketFlags.None);
            //    //        var strData = Encoding.UTF8.GetString(buffer, 0, received);
            //    //        if (!string.IsNullOrEmpty(strData))
            //    //        {
            //    //            if (!string.IsNullOrEmpty(strData))
            //    //            {
            //    //                HJ212_2017 hj = new HJ212_2017();
            //    //                if (hj.DecodeData(strData))
            //    //                {
            //    //                    Console.WriteLine($"客户端发来数据:{strData}");
            //    //                    var body = JsonConvert.SerializeObject(hj.CP);
            //    //                    var entity = JsonConvert.DeserializeObject(body);
            //    //                    entity.deviceId = hj.DATA_HEAD["MN"];
            //    //                    //校验通过,开始入库
            //    //                    Console.WriteLine($"数据开始入库");
            //    //                    _ = _hj212Service.Add(entity, handler.RemoteEndPoint.ToString());
            //    //                    Console.WriteLine($"数据入库end");
            //    //                }
            //    //            }
            //    //        }
            //    //    }
            //    //    else
            //    //    {
            //    //        break;
            //    //    }
            //    //}
            //    //连接客户端
            //}
            //catch (Exception ex)
            //{
            //    Console.WriteLine($"socket服务异常:{ex}");
            //}
        }
        private void OnClient_Connected()
        {
            string message = "##0285QN=20190925181031464;ST=22;CN=2061;PW=BF470F88957588DE902D1A52;MN=Z13401000010301;Flag=5;CP=&&DataTime=20190924220000;a34006-Avg=2.69700,a34006-Flag=N;a34007-Avg=7.96600,a34007-Flag=N;a34048-Avg=3.30600,a34048-Flag=N;a34047-Avg=7.35700,a34047-Flag=N;a34049-Avg=10.66300,a34049-Flag=N&&C181\r\n";
            byte[] data = Encoding.UTF8.GetBytes(message);
            client.SendAsync(data);
        }
        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 void OnNetServer_ReceivedData(TcpSession session, NetPackage netPackage, string rawText)
        {
            Console.WriteLine("收到自: " + session.RemoteIPEndPoint + ": " + rawText);
            HJ212_2017 hj = new HJ212_2017();
            if (hj.DecodeData(rawText))
            {
                var body = JsonConvert.SerializeObject(hj.CP);
                var entity = JsonConvert.DeserializeObject(body);
                entity.deviceId = hj.DATA_HEAD["MN"];
                //校验通过,开始入库
                Console.WriteLine($"数据开始入库");
                _ = _hj212Service.Add(entity, session.RemoteIPEndPoint.ToString());
            }
        }
        private void OnNetServer_ExceptionCaught(Exception ex)
        {
            Console.WriteLine("Error in NetServer" + ex);
        }
        private void Receive(Socket socket)
        {
            string strData = null;
            byte[] bytes = null;
            while (true)
            {
                bytes = new byte[1024];
                int bytesRec = socket.Receive(bytes);
                strData = Encoding.UTF8.GetString(bytes, 0, bytesRec);
                if (!string.IsNullOrEmpty(strData))
                {
                    HJ212_2017 hj = new HJ212_2017();
                    if (hj.DecodeData(strData))
                    {
                        Console.WriteLine($"客户端发来数据:{strData}");
                        var body = JsonConvert.SerializeObject(hj.CP);
                        var entity = JsonConvert.DeserializeObject(body);
                        entity.deviceId = hj.DATA_HEAD["MN"];
                        //校验通过,开始入库
                        Console.WriteLine($"数据开始入库");
                        _ = _hj212Service.Add(entity, socket.RemoteEndPoint.ToString());
                    }
                }
            }
        }
        /// 
        /// 后台线程接收数据
        /// 
        /// 
        private void ReceiveMessage(object obj)
        {
            Socket _ClientSocket = (Socket)obj;
            while (true)
            {
                try
                {
                    //获取数据长度 
                    int receiveLength = _ClientSocket.Receive(result);
                    //获取客户端发来的数据 
                    string strData = Encoding.UTF8.GetString(result, 0, receiveLength);
                    if (string.IsNullOrEmpty(strData))
                    {
                        break;
                    }
                    HJ212_2017 hj = new HJ212_2017();
                    if (hj.DecodeData(strData))
                    {
                        var body = JsonConvert.SerializeObject(hj.CP);
                        var entity = JsonConvert.DeserializeObject(body);
                        entity.deviceId = hj.DATA_HEAD["MN"];
                        //校验通过,开始入库
                        _ = _hj212Service.Add(entity, _ClientSocket.RemoteEndPoint.ToString());
                        _ClientSocket.Close();
                        _ClientSocket.Dispose();
                    }
                }
                catch (Exception e)//通讯出现异常 
                {
                    //从客户端列表中移除该客户端 
                    //this.ClientSockets.Remove(_ClientSocket);
                    ////断开连接 
                    Console.WriteLine($"客户端{_ClientSocket.RemoteEndPoint},通讯出现异常:{e.Message}");
                    //_ClientSocket.Shutdown(SocketShutdown.Both);
                    _ClientSocket.Close();
                    break;
                }
            }
        }
        byte[] PackData(string data)
        {
            Encoding gb = Encoding.GetEncoding("gb2312");
            List arr = new List();
            arr.Add(0x23);
            arr.Add(0x23);//固定包头##
            arr.AddRange(Encoding.ASCII.GetBytes(data.Length.ToString().PadLeft(4, '0')));//数据段字符串长度(长度不足4左补0)的ASCII编码
            byte[] dataSegment = gb.GetBytes(data);//数据段的gb2312编码
            arr.AddRange(dataSegment);
            arr.AddRange(CallCRC(dataSegment));//  CRC-16/Modbus校验值 4个字节
            arr.Add(0x0D);//回车
            arr.Add(0x0A);//换行
            return arr.ToArray();
        }
        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;
        }
    }
}