//===-- UDPSocket.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

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

#include "lldb/Host/Config.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#if LLDB_ENABLE_POSIX
#include <arpa/inet.h>
#include <sys/socket.h>
#endif

#include <memory>

using namespace lldb;
using namespace lldb_private;

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

static const char *g_not_supported_error = "Not supported";

UDPSocket::UDPSocket(NativeSocket socket)
    : Socket(ProtocolUdp, /*should_close=*/true) {
  m_socket = socket;
}

UDPSocket::UDPSocket(bool should_close) : Socket(ProtocolUdp, should_close) {}

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

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

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

llvm::Expected<std::unique_ptr<UDPSocket>>
UDPSocket::CreateConnected(llvm::StringRef name) {
  std::unique_ptr<UDPSocket> socket;

  Log *log = GetLog(LLDBLog::Connection);
  LLDB_LOG(log, "host/port = {0}", name);

  Status error;
  llvm::Expected<HostAndPort> host_port = DecodeHostAndPort(name);
  if (!host_port)
    return host_port.takeError();

  // 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_port->hostname.c_str(), std::to_string(host_port->port).c_str(), &hints,
                          &service_info_list);
  if (err != 0) {
    error = Status::FromErrorStringWithFormat(
#if defined(_WIN32) && defined(UNICODE)
        "getaddrinfo(%s, %d, &hints, &info) returned error %i (%S)",
#else
        "getaddrinfo(%s, %d, &hints, &info) returned error %i (%s)",
#endif
        host_port->hostname.c_str(), host_port->port, err, gai_strerror(err));
    return error.ToError();
  }

  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, error);
    if (error.Success()) {
      socket.reset(new UDPSocket(send_fd));
      socket->m_sockaddr = service_info_ptr;
      break;
    } else
      continue;
  }

  ::freeaddrinfo(service_info_list);

  if (!socket)
    return error.ToError();

  SocketAddress bind_addr;

  // Only bind to the loopback address if we are expecting a connection from
  // localhost to avoid any firewall issues.
  const bool bind_addr_success = (host_port->hostname == "127.0.0.1" || host_port->hostname == "localhost")
                                     ? bind_addr.SetToLocalhost(kDomain, host_port->port)
                                     : bind_addr.SetToAnyAddress(kDomain, host_port->port);

  if (!bind_addr_success) {
    error = Status::FromErrorString("Failed to get hostspec to bind for");
    return error.ToError();
  }

  bind_addr.SetPort(0); // Let the source port # be determined dynamically

  err = ::bind(socket->GetNativeSocket(), bind_addr, bind_addr.GetLength());

  struct sockaddr_in source_info;
  socklen_t address_len = sizeof (struct sockaddr_in);
  err = ::getsockname(socket->GetNativeSocket(),
                      (struct sockaddr *)&source_info, &address_len);

  return std::move(socket);
}

std::string UDPSocket::GetRemoteConnectionURI() const {
  if (m_socket != kInvalidSocketValue) {
    return std::string(llvm::formatv(
        "udp://[{0}]:{1}", m_sockaddr.GetIPAddress(), m_sockaddr.GetPort()));
  }
  return "";
}
