#ifndef POLYGUN_NETWORK_NETWORK_MANAGER_HPP
#define POLYGUN_NETWORK_NETWORK_MANAGER_HPP

#include "common/network/network_packet.hpp"
#include "common/network/udp_socket.hpp"

namespace polygun::network {
	class NetworkManager final {
	public:
		struct QueuedPacket {
			NetworkPacket m_packet;
			double m_last_retry;
			uint8_t m_retries;
		};
	public:
		NetworkManager(const UDPSocket& socket);
		NetworkManager(const std::string& ip, unsigned short port);
		~NetworkManager() = default;

		NetworkPacket create_packet(uint8_t flags, uint8_t id);

		void send_packet(const NetworkPacket& packet);
		bool recv_packet(NetworkPacket& packet);

		void update();

	private:
		uint32_t m_outgoing_packet_counter;
		uint32_t m_incoming_packet_counter;
		std::vector<QueuedPacket> m_outgoing_packets;
		std::vector<QueuedPacket> m_incoming_packets;
		UDPSocket m_socket;

	private:
		void send_ack(uint32_t packet_num) const;
		static void sort_packets(std::vector<QueuedPacket>& packets);
	};
}

#endif // POLYGUN_NETWORK_NETWORK_MANAGER_HPP
