//
// Created by brett on 25/10/23.
//

#ifndef INSANE_DNS_IP_H
#define INSANE_DNS_IP_H

#include <blt/std/string.h>
#include <blt/std/assert.h>
#include <asio.hpp>

using asio::ip::udp;
using asio::ip::tcp;

struct IPAddress
{
    unsigned char octets[4];
    std::string asString;
    
    constexpr IPAddress(std::string str)
    {
        auto data = blt::string::split(str, '.');
        BLT_ASSERT(data.size() == 4);
        for (size_t i = 0; i < data.size(); i++)
            octets[i] = static_cast<unsigned char>(std::stoul(data[i]));
        asString = std::move(str);
    }
    
    constexpr IPAddress(unsigned char oct[4])
    {
        // ugly sin
        for (int i = 0; i < 4; i++)
            octets[i] = oct[i];
    }
};

template<typename IN, typename OUT>
void sendUDPMessage(const std::string& host, const IN& in, size_t in_size, OUT& out, size_t& out_size)
{
    asio::io_context io_context;
    udp::resolver resolver(io_context);
    udp::endpoint receiver_endpoint(asio::ip::address::from_string(host), 53);
    
    udp::socket socket(io_context);
    socket.open(udp::v4());
    
    socket.send_to(asio::const_buffers_1(in, in_size), receiver_endpoint);
    
    udp::endpoint sender_endpoint;
    out_size = socket.receive_from(asio::buffer(out), sender_endpoint);
}

#endif //INSANE_DNS_IP_H
