#include "TestPeerNode.hpp"

#include <chrono>
#include <spdlog/spdlog.h>

namespace tw::p2p {

TestPeerNode::TestPeerNode(uint32_t self_id, uint16_t port,
                           std::unique_ptr<PeerLink> link,
                           const std::string& registry_path,
                           const std::string& csv_path)
    : m_world()
    , m_controller(self_id, port, std::move(link), registry_path, &m_world)
    , m_csv(csv_path)
{
    m_csv << "entity_id,x,y,z,timestamp_ms\n";
}

void TestPeerNode::register_self() {
    m_controller.register_self();
}

bool TestPeerNode::wait_until_peers_registered(uint32_t expected_count,
                                                std::chrono::milliseconds timeout)
{
    return m_controller.wait_until_peers_registered(expected_count, timeout);
}

void TestPeerNode::discover_and_connect() {
    m_controller.discover_and_connect();
}

void TestPeerNode::wait_for_connections(uint32_t expected_count,
                                        std::chrono::milliseconds timeout)
{
    m_controller.wait_for_connections(expected_count, timeout);
}

void TestPeerNode::tick() {
    if (m_controller.tick()) {}
    write_csv_row();
}

void TestPeerNode::write_csv_row() {
    auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
        std::chrono::system_clock::now().time_since_epoch()).count();

    uint32_t self = m_controller.self_id();
    glm::vec3 sp  = m_controller.peer_position(self);
    m_csv << self << "," << sp.x << "," << sp.y << "," << sp.z << "," << now_ms << "\n";

    for (uint32_t pid : m_controller.peer_ids()) {
        glm::vec3 p = m_controller.peer_position(pid);
        m_csv << pid << "," << p.x << "," << p.y << "," << p.z << "," << now_ms << "\n";
    }
}

} // namespace tw::p2p
