#pragma once

#include "blitz/misc/DataBuffer.h"

#include <memory>

namespace blitz {
namespace protocol {

class PacketHandler;


/////////////////////////////////////////////
//			  Packet Structure             //
/////////////////////////////////////////////
//				   ///					   //
//     PacketID    ///      PacketData     //
//				   ///					   //
/////////////////////////////////////////////
//				   ///					   //
//		1 byte     ///		varying size   //
//				   ///					   //
/////////////////////////////////////////////


enum class PacketType : std::uint8_t {
	// client --> server
	PlayerLogin = 0,

	// client <-- server
	ConnectionInfo,
	PlayerJoin,
	PlayerLeave,
	PlayerList,
	ServerTps,

	// client <--> server
	KeepAlive,
	Disconnect,
	Chat,

	PACKET_COUNT
};

class Packet {
  public:
	Packet() {}
	virtual ~Packet() {}

	virtual DataBuffer Serialize(bool packetID = true) const = 0;
	virtual void Deserialize(DataBuffer& data) = 0;
	virtual void Dispatch(PacketHandler* handler) const = 0;

	void WritePacketID(DataBuffer& data, bool packetID) const;

	virtual PacketType GetType() const = 0;

	std::uint8_t GetID() const {
		return static_cast<std::uint8_t>(GetType());
	}
};

typedef std::unique_ptr<Packet> PacketPtr;

}  // namespace protocol
}  // namespace blitz