#include "ZoneClusterLink.hpp"

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

namespace tw::net {

namespace {

std::unique_ptr<msg::MessageEndpoint> bind_endpoint(int port) {
    auto endpoint_r = msg::MessageEndpoint::bind(port);
    if(!endpoint_r) {
        throw std::runtime_error("ZoneClusterLink: failed to bind to port " + std::to_string(port) +
                                 ": " + endpoint_r.error().message());
    }

    return std::move(endpoint_r.value());
}

}

ZoneClusterLink::ZoneClusterLink(int port) :
    m_endpoint(bind_endpoint(port)),
    m_messages(m_endpoint.get()) {
    m_endpoint->set_on_peer_connected([](msg::PeerId peer) {
        spdlog::info("Zone peer {} connected", peer);
    });

    spdlog::info("ZoneClusterLink listening on port {}", port);
}

void ZoneClusterLink::update() {
    m_endpoint->update();
}

msg::MessageConnection* ZoneClusterLink::connect_to_peer(const std::string& host, int port) {
    auto peer_r = m_endpoint->connect(host, port);
    if (!peer_r) {
        spdlog::error("ZoneClusterLink: failed to connect to peer {}:{}: {}",
                      host, port, peer_r.error().message());
        return nullptr;
    }

    spdlog::info("ZoneClusterLink: connected to peer {}:{}", host, port);
    return peer_r.value();
}

} // namespace tw::net
