using System;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace ServerFix
{
    class HandleServer
    {
        Socket ClientSocket;
        Socket ConnectSocket;
        HandleListener LHandle;
        HandleClient CHandle;
        Byte[] ConnectBuffer;

        public HandleServer(Socket HandleSocket, HandleListener HandleListen, HandleClient HandleConnect)
        {
            ClientSocket = HandleSocket;
            LHandle = HandleListen;
            CHandle = HandleConnect;

            try
            {
                IPAddress ConnectIP = IPAddress.Parse(LHandle.Connect_IP);
                IPEndPoint ConnectEndPoint = new IPEndPoint(ConnectIP, LHandle.Connect_Port);

                ConnectSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                ConnectSocket.ReceiveTimeout = 500;
                ConnectSocket.BeginConnect(ConnectEndPoint, new AsyncCallback(ServerConnect), null);
            }
            catch (Exception Error)
            { 
                Program.System.WriteError(Error.Message);

                Shutdown();
            }
        }

        private void ServerConnect(IAsyncResult Result)
        {
            try
            {
                ConnectSocket.EndConnect(Result);

                ConnectBuffer = new Byte[Program.Byte_Size];

                ConnectSocket.BeginReceive(ConnectBuffer, 0, ConnectBuffer.Length, SocketFlags.None, new AsyncCallback(ServerReceive), null);
            }
            catch (Exception Error)
            { 
                Program.System.WriteError(Error.Message);

                Shutdown();
            }
        }

        private void ServerReceive(IAsyncResult Result)
        {
            try
            {
                Int32 ReceiveLength = ConnectSocket.EndReceive(Result);

                Array.Resize(ref ConnectBuffer, ReceiveLength);

                if (Program.BytesToHex(ConnectBuffer).StartsWith("22") && ReceiveLength == 38) { ClientSocket.Close(); return; }

                ClientSocket.Send(ConnectBuffer);

                if (ReceiveLength != 0)
                {
                    ConnectBuffer = new Byte[Program.Byte_Size];

                    ConnectSocket.BeginReceive(ConnectBuffer, 0, ConnectBuffer.Length, SocketFlags.None, new AsyncCallback(ServerReceive), null);
                }
            }
            catch (Exception Error)
            {
                Program.System.WriteError(Error.Message);

                Shutdown();
            }
        }

        private void Shutdown()
        {
            try
            {
                ConnectSocket.Shutdown(SocketShutdown.Both);
                ConnectSocket.Disconnect(false);
                ConnectSocket.Close();

                if (ClientSocket != null) { ClientSocket.Dispose(); }
            }
            catch { }
        }

        public void Send(Byte[] Buffer)
        {
            try
            {
                ConnectSocket.Send(Buffer);
            }
            catch { }
        }
    }
}
