#pragma once

/**
 * \file Connexion.h
 * \brief File containing the blitz::network::Connexion class
 */

#include "TCPSocket.h"
#include "blitz/protocol/PacketDispatcher.h"
#include "blitz/protocol/PacketHandler.h"

namespace blitz {
namespace network {

/**
 * \class Connexion
 * \brief Represents a network connexion
 */
class Connexion : public protocol::PacketHandler, private NonCopyable {
  protected:
	protocol::PacketDispatcher m_Dispatcher;

  private:
	TCPSocket m_Socket;

  public:
	/**
	 * \brief Constructs with an empty socket
	 */
	Connexion(protocol::PacketDispatcher* dispatcher);

	/**
	 * \brief Constructs with an already connected socket
	 */
	Connexion(protocol::PacketDispatcher* dispatcher, TCPSocket& socket);

	/**
	 * \brief Move constructor
	 */
	Connexion(Connexion&& move);

	/**
	 * \brief Default destructor
	*/
	virtual ~Connexion();

	/**
	 * \brief Reads socket and process a Packet, if any 
	*/
	virtual bool UpdateSocket();
	
	/**
	 * \brief Closes the connexion
	*/
	void CloseConnection();

	/**
	 * \brief Tries to connect the socket at the specified address and port
	 * \return Wether this action was succesfull
	*/
	virtual bool Connect(const std::string& address, std::uint16_t port);

	/**
	 * \brief Returns the TCPSocket::Status of the internal socket
	*/
	TCPSocket::Status GetSocketStatus() const {
		return m_Socket.GetStatus();
	}

	/**
	 * \brief Sends the protocol::Packet over the network to the remote
	 * \param packet The protocol::Packet to send
	*/
	void SendPacket(const protocol::Packet* packet);
};

}  // namespace network
}  // namespace blitz
