#include "NetworkInterface.h"

#include <blitz/protocol/PacketFactory.h>
#include <blitz/protocol/PacketSerializer.h>
#include <godot_cpp/classes/multiplayer_api.hpp>
#include <godot_cpp/classes/multiplayer_peer.hpp>
#include <godot_cpp/variant/utility_functions.hpp>

namespace blitz {

using namespace godot;

void NetworkInterface::_bind_methods() {
	ClassDB::bind_method(D_METHOD("RecievePacketDataReliable", "a_PacketData"), &NetworkInterface::RecievePacketDataReliable);
	protocol::PacketFactory::Init();
}

NetworkInterface::NetworkInterface() {}

NetworkInterface::~NetworkInterface() {}

void NetworkInterface::_ready() {
	// TODO: unreliable
	Dictionary config;
	config["rpc_mode"] = MultiplayerAPI::RPC_MODE_ANY_PEER;
	config["transfer_mode"] = MultiplayerPeer::TRANSFER_MODE_RELIABLE;
	config["call_local"] = true;
	config["channel"] = 0;
	rpc_config("RecievePacketDataReliable", config);
}

void NetworkInterface::BroadcastPacket(const protocol::Packet& a_Packet) {
	PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet);
	rpc("RecievePacketDataReliable", byteArray);
}

void NetworkInterface::SendPacket(PeerID a_Peer, const protocol::Packet& a_Packet) {
	PackedByteArray byteArray = protocol::PacketSerializer::Serialize(a_Packet);
	rpc_id(a_Peer, "RecievePacketDataReliable", byteArray);
}

void NetworkInterface::RecievePacketDataReliable(godot::PackedByteArray a_PacketData) {
	auto packet = protocol::PacketSerializer::Deserialize(a_PacketData);
	if (packet) {
		packet->m_Sender = get_multiplayer()->get_remote_sender_id();
		Dispatch(*packet);
	}
}

}  // namespace blitz