using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Net.Sockets;
using FiestaBot;
//using FiestaBot.Login.Handlers;

using FiestaBot.Instances.Networking;
using FiestaBot.Utilities;

namespace FiestaBot.Login.Networking
{
    internal class LoginClient : Client, IDisposable
    {
        public FiestaCrypto Crypto;

        public bool InWorldSelect = false;

        public LoginClient(IPAddress ConnectIP, int Port) : base(ConnectIP, Port)
        {
            Program.LoginClient = this;
        }
        
        public void SendPacket(Packet ServerPacket)
        {
            if (IsConnected != 0) { return; }
            ServerPacket.ToArray(Crypto, out byte[] PacketBuffer);
            ServerPacket.Dispose();

            Send(PacketBuffer);
        }

        public override void Connected()
        {
            Receive();
            Logger.Log(LogType.Socket, "Succesfully connected to the login server");

        }

        public override void ConnectFailed(SocketException Exception) { }

        public override void Received(byte[] Buffer)
        {
           Packet ClientPacket = new Packet(Buffer);
            
            if (!ClientPacket.SetHeaderAndType()) { Logger.Log(LogType.Login, "Unable to read packet header/type"); }
            else if (Program.LoginHandlers.HasHandler(ClientPacket.Header, ClientPacket.Type))
            {
                try
                {
                    MethodInfo PacketMethod = Program.LoginHandlers.GetHandler(ClientPacket.Header, ClientPacket.Type);

                    Action PacketAction = Program.LoginHandlers.GetAction(PacketMethod, this, ClientPacket);
                    PacketAction();
                }
                catch { Logger.Log(LogType.Login, "Unknown packet found: {0}:{1}", ClientPacket.Header, ClientPacket.Type); }
            }
            else { Logger.Log(LogType.Login, "Unknown packet: {0}:{1}", ClientPacket.Header, ClientPacket.Type); }
            
        }

        public override void Disconnected()
        {
            Logger.Log(LogType.Socket, "Disconnected from login");
        }
    }

}
