//===-- UdpSocket.cpp -------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/common/UDPSocket.h"

#include "lldb/Core/Log.h"
#include "lldb/Host/Config.h"

#ifndef LLDB_DISABLE_POSIX
#include <arpa/inet.h>
#include <sys/socket.h>
#endif

#include <memory>

using namespace lldb;
using namespace lldb_private;

namespace {

const int kDomain = AF_INET;
const int kType   = SOCK_DGRAM;

static const char *g_not_supported_error = "Not supported";

}

UDPSocket::UDPSocket(NativeSocket socket)
    : Socket(socket, ProtocolUdp, true)
{
}

UDPSocket::UDPSocket(bool child_processes_inherit, Error &error)
    : UDPSocket(CreateSocket(kDomain, kType, 0, child_processes_inherit, error))
{
}

size_t
UDPSocket::Send(const void *buf, const size_t num_bytes)
{
    return ::sendto (m_socket,
                     static_cast<const char*>(buf),
                     num_bytes,
                     0,
                     m_send_sockaddr,
                     m_send_sockaddr.GetLength());
}

Error
UDPSocket::Connect(llvm::StringRef name)
{
    return Error("%s", g_not_supported_error);
}

Error
UDPSocket::Listen(llvm::StringRef name, int backlog)
{
    return Error("%s", g_not_supported_error);
}

Error
UDPSocket::Accept(llvm::StringRef name, bool child_processes_inherit, Socket *&socket)
{
    return Error("%s", g_not_supported_error);
}

Error
UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, Socket *&send_socket, Socket *&recv_socket)
{
    std::unique_ptr<UDPSocket> final_send_socket;
    std::unique_ptr<UDPSocket> final_recv_socket;

    Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_CONNECTION));
    if (log)
        log->Printf ("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());

    Error error;
    std::string host_str;
    std::string port_str;
    int32_t port = INT32_MIN;
    if (!DecodeHostAndPort (name, host_str, port_str, port, &error))
        return error;

    // Setup the receiving end of the UDP connection on this localhost
    // on port zero. After we bind to port zero we can read the port.
    final_recv_socket.reset(new UDPSocket(child_processes_inherit, error));
    if (error.Success())
    {
        // Socket was created, now lets bind to the requested port
        SocketAddress addr;
        addr.SetToAnyAddress (AF_INET, 0);

        if (::bind (final_recv_socket->GetNativeSocket(), addr, addr.GetLength()) == -1)
        {
            // Bind failed...
            SetLastError (error);
        }
    }

    assert(error.Fail() == !(final_recv_socket && final_recv_socket->IsValid()));
    if (error.Fail())
        return error;

    // At this point we have setup the receive port, now we need to
    // setup the UDP send socket

    struct addrinfo hints;
    struct addrinfo *service_info_list = nullptr;

    ::memset (&hints, 0, sizeof(hints));
    hints.ai_family = kDomain;
    hints.ai_socktype = kType;
    int err = ::getaddrinfo (host_str.c_str(), port_str.c_str(), &hints, &service_info_list);
    if (err != 0)
    {
        error.SetErrorStringWithFormat("getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)",
                                       host_str.c_str(),
                                       port_str.c_str(),
                                       err,
                                       gai_strerror(err));
        return error;
    }

    for (struct addrinfo *service_info_ptr = service_info_list;
         service_info_ptr != nullptr;
         service_info_ptr = service_info_ptr->ai_next)
    {
        auto send_fd = CreateSocket (service_info_ptr->ai_family,
                                     service_info_ptr->ai_socktype,
                                     service_info_ptr->ai_protocol,
                                     child_processes_inherit,
                                     error);
        if (error.Success())
        {
            final_send_socket.reset(new UDPSocket(send_fd));
            final_send_socket->m_send_sockaddr = service_info_ptr;
            break;
        }
        else
            continue;
    }

    :: freeaddrinfo (service_info_list);

    if (!final_send_socket)
        return error;

    send_socket = final_send_socket.release();
    recv_socket = final_recv_socket.release();
    error.Clear();
    return error;
}
