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;

//STATIC 일반적으로 쓸 공용
namespace SystemX.Common
{
    public class ResultEventArgs : EventArgs
    {
        public bool bProcReuslt { get; set; }

        public ResultEventArgs(bool bGetResult)
        {
            bProcReuslt = bGetResult;
        }
        ~ResultEventArgs()
        {
        }
    }

    public class ScheduleEvent : EventArgs
    {
        public int CALL_NUMBER { get; set; }
        public bool PROCESS_RESULT { get; set; }
        public string STATE_MSG { get; set; }
        public byte nLABEL { get; set; }

        public ScheduleEvent(int iCallNumer, bool bState, string strMsg, byte nLabel)
        {
            CALL_NUMBER = iCallNumer;

            PROCESS_RESULT = bState;

            STATE_MSG = strMsg;

            nLABEL = nLabel;
        }

        ~ScheduleEvent()
        {
        }
    }

    public delegate void SendRecvCallEvent(byte[] sender, ScheduleEvent e);
    public delegate void SocketCallEvent(object sender, ScheduleEvent e);

    //SystemXNetCommons
    public static partial class XCommons
    {
        [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern int memcmp(byte[] b1, byte[] b2, long count);

        public static bool ByteArrayCompare(byte[] ucArr1, byte[] ucArr2)
        {
            if (ucArr1 == null || ucArr2 == null)
                return false;
            if (ucArr1.Length != ucArr2.Length)
                return false;

            // Validate buffers are the same length.
            // This also ensures that the count does not exceed the length of either buffer. 
            return (memcmp(ucArr1, ucArr2, ucArr1.Length) == 0);
        }


        public const int PAD_SIZE = 12;
        private const int HEAD_SIZE = 8;
        private const int TAIL_SIZE = 4;

        public static bool isHasRow(DataSet ds)
        {
            return (ds != null) ? ds.Tables.Cast<DataTable>().Any(table => table.Rows.Count != 0) : false;
        }

        public static bool isHasRow(DataTable dt)
        {
            return (dt != null) ? dt.Rows.Count > 0 : false;
        }

        //
        // 요약:
        //     패킷 압축 및 마샬링 패킷 마샬링 및 압축 해제시 
        public class CommonPacketMarshalException : Exception
        {
            public CommonPacketMarshalException()
            {
            }

            public CommonPacketMarshalException(string message)
                : base(message)
            {
            }

            public CommonPacketMarshalException(string message, Exception inner)
                : base(message, inner)
            {
            }
        }

        public static BASE_PROTOCOL GetHeaderProtocol(int iSize, byte[] CompressMarshalByteStream)
        {
            byte[] ucDecompressGetByte = new byte[1];
            byte[] getRowByte = new byte[iSize - PAD_SIZE];

            BASE_PROTOCOL SET_PROTOCOL = new BASE_PROTOCOL();

            try
            {
                try
                {
                    Array.Copy(CompressMarshalByteStream, HEAD_SIZE, getRowByte, 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(getRowByte, 0, ucHeadBytes, 0, iHeadLeng);

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

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

            return SET_PROTOCOL;
        }
        public static HEADER_PACKET GetHeaderPacket(int iSize, byte[] CompressMarshalByteStream)
        {
            byte[] ucDecompressGetByte = new byte[1];
            byte[] getRowByte = new byte[iSize - PAD_SIZE];

            HEADER_PACKET GetHeaderPacket = new HEADER_PACKET();

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

                    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(getRowByte, 0, ucHeadBytes, 0, iHeadLeng);

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

            return GetHeaderPacket;
        }
        private static byte[] HeadTailMake(uint uiPacketSize, byte[] HeadBuff, byte[] BodyBuff)
        {
            byte[] ucSetStreamBytes = new byte[uiPacketSize + PAD_SIZE];

            ucSetStreamBytes[0] = 0x0D;
            ucSetStreamBytes[1] = 0x02;
            ucSetStreamBytes[2] = (byte)(uiPacketSize >> 24);
            ucSetStreamBytes[3] = (byte)(uiPacketSize >> 16);
            ucSetStreamBytes[4] = (byte)(uiPacketSize >> 8);
            ucSetStreamBytes[5] = (byte)(uiPacketSize >> 0);
            ucSetStreamBytes[6] = 0x08;
            ucSetStreamBytes[7] = 0x0A;

            Array.Copy(HeadBuff, 0, ucSetStreamBytes, 8, HeadBuff.Count());
            Array.Copy(BodyBuff, 0, ucSetStreamBytes, HeadBuff.Count() + HEAD_SIZE, BodyBuff.Count());

            ucSetStreamBytes[ucSetStreamBytes.Length - 4] = 0x0D;
            ucSetStreamBytes[ucSetStreamBytes.Length - 3] = 0x02;
            ucSetStreamBytes[ucSetStreamBytes.Length - 2] = 0x08;
            ucSetStreamBytes[ucSetStreamBytes.Length - 1] = 0x0A;

            return ucSetStreamBytes;
        }
    }
}
