#if COMBAT_SERVER
using System;
using System.Net;
using System.Net.Sockets;
using Com.Fort23.Protocol.Protobuf;
using Fort23.UTool;

namespace Core.KCPTool
{
    public class TCPServerConnection : IServerConnection
    {
        public bool isConnected { get; set; }
        public int connectionID { get; set; }
        public long playerId { get; set; }
        public IPEndPoint EndPoint { get; set; }


        private byte[] buffData = new byte[6553];
        private Socket socket;

        //记录半包数据
        private bool isBufferData;
        private byte[] lastBuffData;
        private int lastCount;

        private short lastSendType;

        //数据结束

        //尾包
        private byte[] weiBaoBuffData;


        private Thread _udpClientThread;


        private TCPServer _tcpServer;

        public TCPServerConnection(TCPServer tcpServer, Socket socket)
        {
            this.socket = socket;
            socket.NoDelay = true;
            _tcpServer = tcpServer;
            isConnected = true;
            _udpClientThread = new Thread(TheUpdate);
            _udpClientThread.Start();
        }


        private void TheUpdate()
        {
            while (socket != null)
            {
                try
                {
                    int count = socket.Receive(buffData);
                    if (count <= 0)
                    {
                        Thread.Sleep(1);
                        return;
                    }

                    // LogTool.Log("数据来了" + count);

                    try
                    {
                        int currCount = 0;
                        int startIndex = 0;

                        // bool isEnd = false;
                        while (currCount < count)
                        {
                            // isEnd = true;
                            byte[] data = null;
                            short sendType = 0;
                            int cdShort = 0;

                            if (!isBufferData)
                            {
                                if (weiBaoBuffData != null)
                                {
                                    int maxCount = 6553500;
                                    if (count + weiBaoBuffData.Length > maxCount)
                                    {
                                        maxCount = count + weiBaoBuffData.Length;
                                    }

                                    // LogTool.Log("修复包太短__" + count + "___" + weiBaoBuffData.Length);
                                    byte[] newBuff = new byte[maxCount];
                                    Array.Copy(weiBaoBuffData, 0, newBuff, 0, weiBaoBuffData.Length);
                                    Array.Copy(buffData, 0, newBuff, weiBaoBuffData.Length, count);

                                    buffData = newBuff;
                                    count += weiBaoBuffData.Length;
                                    // LogTool.Log("修复包后太短__" + count);
                                    if (count < 6)
                                    {
                                        weiBaoBuffData = new byte[count];
                                        // LogTool.Log("包太短222__" + count);
                                        Array.Copy(buffData, currCount, weiBaoBuffData, 0, count);
                                        break;
                                    }
                                    else
                                    {
                                        weiBaoBuffData = null;
                                    }
                                }
                                else
                                {
                                    if (count - currCount < 6)
                                    {
                                        weiBaoBuffData = new byte[count];
                                        // LogTool.Log("包太短__" + count);
                                        Array.Copy(buffData, currCount, weiBaoBuffData, 0, count);
                                        break;
                                    }
                                }
                            }

                            if (!isBufferData)
                            {
                                sendType = buffData[currCount];
                                currCount++;
                                byte[] dataBuffLanl = new byte[4];
                                dataBuffLanl[0] = buffData[currCount];
                                currCount++;
                                dataBuffLanl[1] = buffData[currCount];
                                currCount++;
                                dataBuffLanl[2] = buffData[currCount];
                                currCount++;
                                dataBuffLanl[3] = buffData[currCount];
                                currCount++;
                                cdShort = (SocketTool.ByteToInt(dataBuffLanl));
                                // LogTool.Log("数据到来" + cdShort + "__" + count + "_" + sendType);
                                if ((currCount + cdShort) > count) //处理半包情况
                                {
                                    lastBuffData = new byte[count - currCount];
                                    lastCount = cdShort;
                                    lastSendType = sendType;
                                    Array.Copy(buffData, currCount, lastBuffData, 0, lastBuffData.Length);
                                    // LogTool.Log("数据只有一半" + count + "__" + currCount + "___" + cdShort);
                                    isBufferData = true;
                                    break;
                                }
                                else
                                {
                                    // LogTool.Log(currCount + "_收到长度：" + cdShort + "_Max" + count);
                                    data = new byte[cdShort];
                                    Array.Copy(buffData, currCount, data, 0, data.Length);
                                }
                            }
                            else if (lastCount - lastBuffData.Length > count)
                            {
                                // LogTool.Log("数据只有一半的一半" + count + "__" + lastCount + "___" + lastBuffData.Length);
                                byte[] newLastBuffData = new byte[lastBuffData.Length + count];
                                Array.Copy(lastBuffData, 0, newLastBuffData, 0, lastBuffData.Length);
                                Array.Copy(buffData, 0, newLastBuffData, lastBuffData.Length, count);
                                lastBuffData = newLastBuffData;
                                break;
                            }

                            else if (lastBuffData != null) //处理半包情况
                            {
                                isBufferData = false;
                                // LogTool.Log("修复半包" + lastCount + "__" + count + "___" +
                                // (lastCount - lastBuffData.Length));
                                sendType = lastSendType;
                                data = new byte[lastCount];
                                cdShort = lastCount - lastBuffData.Length;
                                Array.Copy(lastBuffData, 0, data, 0, lastBuffData.Length);
                                Array.Copy(buffData, currCount, data, lastBuffData.Length, cdShort);
                            }

                            SendDataType sendDataType = (SendDataType)sendType;
                            switch (sendDataType)
                            {
                                case SendDataType.ShakeHands:
                                    // int gameFrame = 0;
                                    // if (data.Length <= 8)
                                    // {
                                    //     long playerId = SocketTool.ByteToLong(data);
                                    //     this.playerId = playerId;
                                    // }
                                    // else
                                {
                                    byte[] pdata = new byte[8];
                                    Array.Copy(data, 0, pdata, 0, pdata.Length);

                                    long playerId = SocketTool.ByteToLong(data);
                                    this.playerId = playerId;
                                    // byte[] fdata = new byte[4];
                                    // Array.Copy(data, 8, fdata, 0, fdata.Length);
                                    //  gameFrame = SocketTool.ByteToInt(fdata);
                                }
                                    _tcpServer.AddServerConnection(playerId, 0, this);
                                    break;
                                case SendDataType.Data:
                                    CombatSynchronizeRequest combatSynchronizeRequest =
                                        CombatSynchronizeRequest.Parser.ParseFrom(data);
                                    if (combatSynchronizeRequest == null)
                                    {
                                        LogTool.Error("错误的实例化战斗" + data.Length);
                                    }
                                    else
                                    {
                                        // LogTool.Error("收到客户端消息" + combatSynchronizeRequest.CombatSynchronizeType);
                                        _tcpServer.AddCombatSynchronizeRequest(combatSynchronizeRequest);
                                    }

                                    break;
                                case SendDataType.GetGameFrameByte:
                                    int gameFrame = 0;
                                    byte[] fdata = new byte[4];
                                    Array.Copy(data, 8, fdata, 0, fdata.Length);
                                    gameFrame = SocketTool.ByteToInt(fdata);

                                    _tcpServer.SendGameFrame(gameFrame, this);
                                    break;
                            }


                            currCount += cdShort;
                            startIndex = currCount;
                        }
                    }
                    catch (Exception e)
                    {
                        LogTool.Exception(e);


                        // LogTool.Log("");
                    }
                }
                catch (Exception e)
                {
                    LogTool.Log(e);
                    isConnected = false;
                    break;
                }
            }

            LogTool.Log("服务器执行完毕");
        }


        public int SendData(byte[] data, int dataSize)
        {
            if (socket == null)
            {
                return -1;
            }

            try
            {
                socket.SendAsync(data);
            }
            catch (Exception e)
            {
                LogTool.Exception(e);
                isConnected = false;
            }

            return 0;
        }

        public void Update()
        {
        }

        public void ReceiveAsync()
        {
        }

        public int Input(byte[] data)
        {
            return 0;
        }

        public void Dispose()
        {
            socket?.Close();
            socket?.Dispose();
            socket = null;
            _tcpServer = null;
            _udpClientThread = null;
        }
    }
}

#endif