using System;
using System.Collections.Concurrent;
using System.IO;
using GameMessage;
using K4os.Compression.LZ4;
using MessagePack;
using MrWu.Debug;
using Server.Core;

namespace Server.Net
{
    public static class PacketUtility
    {
        private static int MaxSendLength = 0;

        private const int LogMinLength = 1024 * 100;

        public static int MessageParseDataV1(byte[] data, Type messageType, MemoryStream memoryStream)
        {
            int opcode = MessageManager.GetOpcode(messageType);
            memoryStream.Seek(5, SeekOrigin.Begin);
            //写入数据
            memoryStream.Write(data,0,data.Length);
            
            int length = (int)memoryStream.Position;
            memoryStream.GetBuffer()[0] = 0;  //设置为不压缩
            memoryStream.GetBuffer().WriteTo(1,opcode);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return length;
        }

        public static int MessageParseDataV1(MessageData messageData,MemoryStream memoryStream,MemoryStream compressStream)
        {
            Type messageType = messageData.GetType();
            int opcode = MessageManager.GetOpcode(messageType);
            
            compressStream.Seek(0, SeekOrigin.Begin);
            MessagePackSerializer.Serialize(messageType,compressStream, messageData);
            
            memoryStream.Seek(5, SeekOrigin.Begin);
            byte compressFlag = 0;
            if (compressStream.Position < 2048) //2k 一下不压缩
            {
                memoryStream.Write(compressStream.GetBuffer(),0,(int)compressStream.Position); //把包内容全部写入
            }
            else
            {
                //压缩处理
                byte[] compressData = LZ4Pickler.Pickle(compressStream.GetBuffer(), 0, (int)compressStream.Position);
                memoryStream.WriteInt((int)compressStream.Position); //写入压缩前的长度
                memoryStream.Write(compressData,0,compressData.Length);
                compressFlag = 1;
                //Debug.Info($"得到数据:{compressData.Length} {compressData[0]} {compressData[compressData.Length - 1]}");
            }
            
            int length = (int)memoryStream.Position;
            memoryStream.GetBuffer()[0] = compressFlag; 
            memoryStream.GetBuffer().WriteTo(1,opcode);
            memoryStream.Seek(0, SeekOrigin.Begin);
            return length;
        }

        public static byte[] MessageParseData(Type messageType,byte[] data)
        {
            int opcode = MessageManager.GetOpcode(messageType);
            int len = 4 + 4 + data.Length;

            //包长度
            byte[] lenData = BitConverter.GetBytes(len);
            //包类型
            byte[] opcodeData = BitConverter.GetBytes(opcode);
            //备用 4个字节
            byte[] bakData = BitConverter.GetBytes(0);
            //发送的数据
            byte[] sendData = new byte[len + 4];

            if (len > MaxSendLength)
            {
                MaxSendLength = len;
                if (MaxSendLength > LogMinLength)
                {
                    Debug.ImportantLog($"当前最大发送数据长度:{MaxSendLength},opcode:{opcode}");
                }
            }


            Buffer.BlockCopy(lenData, 0, sendData, 0, 4);
            Buffer.BlockCopy(opcodeData, 0, sendData, 4, 4);
            Buffer.BlockCopy(bakData, 0, sendData, 8, 4);
            Buffer.BlockCopy(data, 0, sendData, 12, data.Length);

            return sendData;
        }
        
        public static byte[] MessageParseData(MessageData messageData)
        {
            Type messageType = messageData.GetType();
            int opcode = MessageManager.GetOpcode(messageType);
            byte[] data = MessagePackSerializer.Serialize(messageType, messageData);
            int len = 4 + 4 + data.Length;

            //包长度
            byte[] lenData = BitConverter.GetBytes(len);
            //包类型
            byte[] opcodeData = BitConverter.GetBytes(opcode);
            //备用 4个字节
            byte[] bakData = BitConverter.GetBytes(0);
            //发送的数据
            byte[] sendData = new byte[len + 4];

            if (len > MaxSendLength)
            {
                MaxSendLength = len;
                if (MaxSendLength > LogMinLength)
                {
                    Debug.ImportantLog($"当前最大发送数据长度:{MaxSendLength},opcode:{opcode}");
                }
            }


            Buffer.BlockCopy(lenData, 0, sendData, 0, 4);
            Buffer.BlockCopy(opcodeData, 0, sendData, 4, 4);
            Buffer.BlockCopy(bakData, 0, sendData, 8, 4);
            Buffer.BlockCopy(data, 0, sendData, 12, data.Length);

            return sendData;
        }
    }
}