using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
using SystemX.Common.Archive;
using SystemX.Common.Serialization;
using SystemX.Net.BaseProtocol;
using static SystemX.Net.Platform.Common.Util.LogMessage;


namespace SystemX.Common
{
    public static partial class XCommons
    {
        public static T ByteStreamToSpecialObject<T>(BASE_PROTOCOL.PROTOCOL_CODE GET_CODE, int iSize, byte[] MarshalByteStream)
        {
            byte[] getDataByte = new byte[1];
            byte[] getRawByte = new byte[iSize - PAD_SIZE];

            int iRawDataSize;

            object getObj = null;

            try
            {
                try
                {
                    Array.Copy(MarshalByteStream, HEAD_SIZE, getRawByte, 0, iSize - PAD_SIZE);

                    HEADER_PACKET GetHeaderPacket = new HEADER_PACKET();
                    int iHeadLeng = Marshal.SizeOf(GetHeaderPacket);
                    byte[] ucHeadBytes = new byte[iHeadLeng];
                    Array.Copy(getRawByte, 0, ucHeadBytes, 0, iHeadLeng);
                    iRawDataSize = getRawByte.Count();
                    GetHeaderPacket = (HEADER_PACKET)SystemXNetSerialization.RawDeSerialize(ucHeadBytes, GetHeaderPacket.GetType());

                    getDataByte = new byte[GetHeaderPacket.uiDataLength];

                    object getPacket = SystemXNetSerialization.SelectPacket(GetHeaderPacket.uiDataLength);
                    if (getPacket == null) throw new Exception("SystemXNetSerialization.SelectPacket Failed.");
                    int iBodySize = Marshal.SizeOf(getPacket);
                    byte[] ucBodyArray = new byte[iBodySize];
                    Array.Copy(getRawByte, iHeadLeng, ucBodyArray, 0, iBodySize); // iRawDataSize - iHeadLeng);

                    getPacket = Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucBodyArray, getPacket.GetType()), getPacket.GetType());
                    getPacket = SystemXNetSerialization.RawDeSerialize(ucBodyArray, getPacket.GetType());

                    Array.Copy((byte[])getPacket.GetType().GetMethod("Data").Invoke(getPacket, null), getDataByte, GetHeaderPacket.uiDataLength);

                    byte[] ucSpecialObjArray = XDataArchive.DecompressDeflateByteToByte(getDataByte);

                    if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.CONNECT_STATE)
                    {
                        PING_PACKET PingPacket = new PING_PACKET();
                        PingPacket = (PING_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, PingPacket.GetType()), PingPacket.GetType());
                        PingPacket = (PING_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, PingPacket.GetType());

                        getObj = PingPacket;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.MIDDLEWARE_MESSAGE)
                    {
                        MESSAGE_PACKET MessagePacket = new MESSAGE_PACKET();
                        MessagePacket = (MESSAGE_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, MessagePacket.GetType()), MessagePacket.GetType());
                        MessagePacket = (MESSAGE_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, MessagePacket.GetType());

                        getObj = MessagePacket;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.HOST_INFO_CHECK)
                    {
                        SYSTEM_HOST_PACKET HostInfoPacket = new SYSTEM_HOST_PACKET();
                        HostInfoPacket = (SYSTEM_HOST_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, HostInfoPacket.GetType()), HostInfoPacket.GetType());
                        HostInfoPacket = (SYSTEM_HOST_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, HostInfoPacket.GetType());

                        getObj = HostInfoPacket;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.SYNC_TIME_SERVER)
                    {
                        TIME_PACKET timePacket = new TIME_PACKET();
                        timePacket = (TIME_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, timePacket.GetType()), timePacket.GetType());
                        timePacket = (TIME_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, timePacket.GetType());

                        getObj = timePacket;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.ETC)
                    {
                        USER_PACKET UserDataPacket = new USER_PACKET();
                        UserDataPacket = (USER_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, UserDataPacket.GetType()), UserDataPacket.GetType());
                        UserDataPacket = (USER_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, UserDataPacket.GetType());

                        getObj = UserDataPacket;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.PROCESS_QUERY)
                    {
                        PROCESS_PACKET ProcessDataPacket = new PROCESS_PACKET();
                        ProcessDataPacket = (PROCESS_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, ProcessDataPacket.GetType()), ProcessDataPacket.GetType());
                        ProcessDataPacket = (PROCESS_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, ProcessDataPacket.GetType());

                        getObj = ProcessDataPacket;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.SYSTEM_QUERY)
                    {
                        QUERY_PACKET SystemQueryPacket = new QUERY_PACKET();
                        SystemQueryPacket = (QUERY_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, SystemQueryPacket.GetType()), SystemQueryPacket.GetType());
                        SystemQueryPacket = (QUERY_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, SystemQueryPacket.GetType());

                        getObj = SystemQueryPacket;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.USER_QUERY)
                    {
                        QUERY_PACKET SystemQueryPacket = new QUERY_PACKET();
                        SystemQueryPacket = (QUERY_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, SystemQueryPacket.GetType()), SystemQueryPacket.GetType());
                        SystemQueryPacket = (QUERY_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, SystemQueryPacket.GetType());

                        getObj = SystemQueryPacket;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.TRANSFER_RESULT)
                    {
                        TRANSFER_PACKET TransferResult = new TRANSFER_PACKET();
                        TransferResult = (TRANSFER_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, TransferResult.GetType()), TransferResult.GetType());
                        TransferResult = (TRANSFER_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, TransferResult.GetType());

                        getObj = TransferResult;
                    }
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.INITILALIZE_INFO)
                    {
                        COMM_INFO_PACKET CommInfoPacket = new COMM_INFO_PACKET();
                        CommInfoPacket = (COMM_INFO_PACKET)Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, CommInfoPacket.GetType()), CommInfoPacket.GetType());
                        CommInfoPacket = (COMM_INFO_PACKET)SystemXNetSerialization.RawDeSerialize(ucSpecialObjArray, CommInfoPacket.GetType());

                        getObj = CommInfoPacket;
                    }
                    else
                        getObj = null;
                }
                catch (Exception e)
                {
                    //throw new CommonPacketMarshalException("General packet marshalling failed.[SystemX.Common : SystemXNetCommons.ByteStreamToUserObject]");
                    MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"General packet marshalling failed.[SystemX.Common : SystemXNetCommons.ByteStreamToUserObject]\r\n" + e.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG);
                }
            }
            finally
            {
                ;//Until unused
            }

            return (T)Convert.ChangeType(getObj, typeof(T));
        }

        public static bool GetSimpleResponsResult(int iSize, byte[] CompressMarshalByteStream)
        {
            byte[] getDataByte = new byte[1];
            byte[] getRawByte = new byte[iSize - PAD_SIZE];

            bool bResponsResult = false;

            try
            {
                try
                {
                    Array.Copy(CompressMarshalByteStream, HEAD_SIZE, getRawByte, 0, iSize - PAD_SIZE);

                    HEADER_PACKET GetHeaderPacket = new HEADER_PACKET();
                    int iHeaderSize = Marshal.SizeOf(GetHeaderPacket);
                    byte[] ucHeaderMake = new byte[iHeaderSize];
                    GetHeaderPacket = (HEADER_PACKET)SystemXNetSerialization.RawDeSerialize(ucHeaderMake, GetHeaderPacket.GetType());
                    int iHeadLeng = Marshal.SizeOf(GetHeaderPacket);

                    byte[] ucHeadBytes = new byte[iHeadLeng];

                    Array.Copy(getRawByte, 0, ucHeadBytes, 0, iHeadLeng);

                    GetHeaderPacket = (HEADER_PACKET)SystemXNetSerialization.RawDeSerialize(ucHeadBytes, GetHeaderPacket.GetType());

                    getDataByte = new byte[GetHeaderPacket.uiDataLength];

                    object getPacket = SystemXNetSerialization.SelectPacket(GetHeaderPacket.uiDataLength);
                    if (getPacket == null) throw new Exception("SystemXNetSerialization.SelectPacket Failed.");
                    int iBodySize = Marshal.SizeOf(getPacket);
                    byte[] ucBodyArray = new byte[iBodySize];
                    Array.Copy(getRawByte, iHeadLeng, ucBodyArray, 0, iBodySize); // - iHeadLeng);

                    getPacket = Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucBodyArray, getPacket.GetType()), getPacket.GetType());
                    getPacket = SystemXNetSerialization.RawDeSerialize(ucBodyArray, getPacket.GetType());

                    Array.Copy((byte[])getPacket.GetType().GetMethod("Data").Invoke(getPacket, null), getDataByte, GetHeaderPacket.uiDataLength);

                    bResponsResult = GetHeaderPacket.bResponsState;
                }
                catch (Exception e)
                {
                    //throw new CommonPacketMarshalException("General packet marshalling failed.[SystemX.Common : SystemXNetCommons.ByteStreamToObject]");
                    MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"General packet marshalling failed.[SystemX.Common : SystemXNetCommons.ByteStreamToObject]\r\n" + e.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG);
                }
            }
            finally
            {
                ;//Until unused
            }

            return bResponsResult;
        }

        public static T ByteStreamToObject<T>(BASE_PROTOCOL.PROTOCOL_CODE GET_CODE, int iSize, byte[] CompressMarshalByteStream)
        {
            byte[] getDataByte = new byte[1];
            byte[] getRawByte = new byte[iSize - PAD_SIZE];

            object getObj = null;

            try
            {
                try
                {
                    Array.Copy(CompressMarshalByteStream, HEAD_SIZE, getRawByte, 0, iSize - PAD_SIZE);

                    HEADER_PACKET GetHeaderPacket = new HEADER_PACKET();
                    int iHeaderSize = Marshal.SizeOf(GetHeaderPacket);
                    byte[] ucHeaderMake = new byte[iHeaderSize];
                    GetHeaderPacket = (HEADER_PACKET)SystemXNetSerialization.RawDeSerialize(ucHeaderMake, GetHeaderPacket.GetType());
                    int iHeadLeng = Marshal.SizeOf(GetHeaderPacket);

                    byte[] ucHeadBytes = new byte[iHeadLeng];

                    Array.Copy(getRawByte, 0, ucHeadBytes, 0, iHeadLeng);

                    GetHeaderPacket = (HEADER_PACKET)SystemXNetSerialization.RawDeSerialize(ucHeadBytes, GetHeaderPacket.GetType());

                    getDataByte = new byte[GetHeaderPacket.uiDataLength];

                    object getPacket = SystemXNetSerialization.SelectPacket(GetHeaderPacket.uiDataLength);
                    if (getPacket == null) throw new Exception("SystemXNetSerialization.SelectPacket Failed.");
                    int iBodySize = Marshal.SizeOf(getPacket);
                    byte[] ucBodyArray = new byte[iBodySize];
                    Array.Copy(getRawByte, iHeadLeng, ucBodyArray, 0, iBodySize); // - iHeadLeng);

                    getPacket = Convert.ChangeType(SystemXNetSerialization.RawDeSerialize(ucBodyArray, getPacket.GetType()), getPacket.GetType());
                    getPacket = SystemXNetSerialization.RawDeSerialize(ucBodyArray, getPacket.GetType());

                    Array.Copy((byte[])getPacket.GetType().GetMethod("Data").Invoke(getPacket, null), getDataByte, GetHeaderPacket.uiDataLength);

                    if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.FILE_TRANSFER)
                        getObj = getDataByte; //XDataArchive.DecompressDeflateByteToByte(getDataByte);
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.DATASET_TRANSEFER)
                        getObj = XDataArchive.DecompressByteToDataset(getDataByte);
                    else if (GET_CODE == BASE_PROTOCOL.PROTOCOL_CODE.RAW_SIZE)
                        getObj = getDataByte;
                }
                catch (Exception e)
                {
                    //throw new CommonPacketMarshalException("General packet marshalling failed.[SystemX.Common : COMMON.ByteStreamToObject]");
                    MessageOutput.ConsoleWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss>>") + @"General packet marshalling failed.[SystemX.Common : COMMON.ByteStreamToObject]\r\n" + e.Message, ConsoleColor.Yellow, LogMessageLevel.DEBUG);
                }
            }
            finally
            {
                ;//Until unused
            }

            return (T)Convert.ChangeType(getObj, typeof(T));
        }
    }
}
