//===-- Socket.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/Socket.h"

#include "lldb/Host/Config.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/MainLoop.h"
#include "lldb/Host/SocketAddress.h"
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/common/UDPSocket.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Errno.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/WindowsError.h"

#if LLDB_ENABLE_POSIX
#include "lldb/Host/posix/DomainSocket.h"

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#endif

#ifdef __linux__
#include "lldb/Host/linux/AbstractSocket.h"
#endif

using namespace lldb;
using namespace lldb_private;

#if defined(_WIN32)
typedef const char *set_socket_option_arg_type;
typedef char *get_socket_option_arg_type;
const NativeSocket Socket::kInvalidSocketValue = INVALID_SOCKET;
const shared_fd_t SharedSocket::kInvalidFD = LLDB_INVALID_PIPE;
#else  // #if defined(_WIN32)
typedef const void *set_socket_option_arg_type;
typedef void *get_socket_option_arg_type;
const NativeSocket Socket::kInvalidSocketValue = -1;
const shared_fd_t SharedSocket::kInvalidFD = Socket::kInvalidSocketValue;
#endif // #if defined(_WIN32)

static bool IsInterrupted() {
#if defined(_WIN32)
  return ::WSAGetLastError() == WSAEINTR;
#else
  return errno == EINTR;
#endif
}

SharedSocket::SharedSocket(const Socket *socket, Status &error) {
#ifdef _WIN32
  m_socket = socket->GetNativeSocket();
  m_fd = kInvalidFD;

  // Create a pipe to transfer WSAPROTOCOL_INFO to the child process.
  error = m_socket_pipe.CreateNew();
  if (error.Fail())
    return;

  m_fd = m_socket_pipe.GetReadPipe();
#else
  m_fd = socket->GetNativeSocket();
  error = Status();
#endif
}

Status SharedSocket::CompleteSending(lldb::pid_t child_pid) {
#ifdef _WIN32
  // Transfer WSAPROTOCOL_INFO to the child process.
  m_socket_pipe.CloseReadFileDescriptor();

  WSAPROTOCOL_INFO protocol_info;
  if (::WSADuplicateSocket(m_socket, child_pid, &protocol_info) ==
      SOCKET_ERROR) {
    int last_error = ::WSAGetLastError();
    return Status::FromErrorStringWithFormat(
        "WSADuplicateSocket() failed, error: %d", last_error);
  }

  llvm::Expected<size_t> num_bytes = m_socket_pipe.Write(
      &protocol_info, sizeof(protocol_info), std::chrono::seconds(10));
  if (!num_bytes)
    return Status::FromError(num_bytes.takeError());
  if (*num_bytes != sizeof(protocol_info))
    return Status::FromErrorStringWithFormatv(
        "Write(WSAPROTOCOL_INFO) failed: wrote {0}/{1} bytes", *num_bytes,
        sizeof(protocol_info));
#endif
  return Status();
}

Status SharedSocket::GetNativeSocket(shared_fd_t fd, NativeSocket &socket) {
#ifdef _WIN32
  socket = Socket::kInvalidSocketValue;
  // Read WSAPROTOCOL_INFO from the parent process and create NativeSocket.
  WSAPROTOCOL_INFO protocol_info;
  {
    Pipe socket_pipe(fd, LLDB_INVALID_PIPE);
    llvm::Expected<size_t> num_bytes = socket_pipe.Read(
        &protocol_info, sizeof(protocol_info), std::chrono::seconds(10));
    if (!num_bytes)
      return Status::FromError(num_bytes.takeError());
    if (*num_bytes != sizeof(protocol_info)) {
      return Status::FromErrorStringWithFormatv(
          "Read(WSAPROTOCOL_INFO) failed: read {0}/{1} bytes", *num_bytes,
          sizeof(protocol_info));
    }
  }
  socket = ::WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
                       FROM_PROTOCOL_INFO, &protocol_info, 0, 0);
  if (socket == INVALID_SOCKET) {
    return Status::FromErrorStringWithFormatv(
        "WSASocket(FROM_PROTOCOL_INFO) failed: error {0}", ::WSAGetLastError());
  }
  return Status();
#else
  socket = fd;
  return Status();
#endif
}

struct SocketScheme {
  const char *m_scheme;
  const Socket::SocketProtocol m_protocol;
};

static SocketScheme socket_schemes[] = {
    {"tcp", Socket::ProtocolTcp},
    {"udp", Socket::ProtocolUdp},
    {"unix", Socket::ProtocolUnixDomain},
    {"unix-abstract", Socket::ProtocolUnixAbstract},
};

const char *
Socket::FindSchemeByProtocol(const Socket::SocketProtocol protocol) {
  for (auto s : socket_schemes) {
    if (s.m_protocol == protocol)
      return s.m_scheme;
  }
  return nullptr;
}

bool Socket::FindProtocolByScheme(const char *scheme,
                                  Socket::SocketProtocol &protocol) {
  for (auto s : socket_schemes) {
    if (!strcmp(s.m_scheme, scheme)) {
      protocol = s.m_protocol;
      return true;
    }
  }
  return false;
}

Socket::Socket(SocketProtocol protocol, bool should_close)
    : IOObject(eFDTypeSocket), m_protocol(protocol),
      m_socket(kInvalidSocketValue), m_should_close_fd(should_close) {}

Socket::~Socket() { Close(); }

llvm::Error Socket::Initialize() {
#if defined(_WIN32)
  auto wVersion = WINSOCK_VERSION;
  WSADATA wsaData;
  int err = ::WSAStartup(wVersion, &wsaData);
  if (err == 0) {
    if (wsaData.wVersion < wVersion) {
      WSACleanup();
      return llvm::createStringError("WSASock version is not expected");
    }
  } else {
    return llvm::errorCodeToError(llvm::mapWindowsError(::WSAGetLastError()));
  }
#endif

  return llvm::Error::success();
}

void Socket::Terminate() {
#if defined(_WIN32)
  ::WSACleanup();
#endif
}

std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,
                                       Status &error) {
  error.Clear();

  const bool should_close = true;
  std::unique_ptr<Socket> socket_up;
  switch (protocol) {
  case ProtocolTcp:
    socket_up = std::make_unique<TCPSocket>(should_close);
    break;
  case ProtocolUdp:
    socket_up = std::make_unique<UDPSocket>(should_close);
    break;
  case ProtocolUnixDomain:
#if LLDB_ENABLE_POSIX
    socket_up = std::make_unique<DomainSocket>(should_close);
#else
    error = Status::FromErrorString(
        "Unix domain sockets are not supported on this platform.");
#endif
    break;
  case ProtocolUnixAbstract:
#ifdef __linux__
    socket_up = std::make_unique<AbstractSocket>();
#else
    error = Status::FromErrorString(
        "Abstract domain sockets are not supported on this platform.");
#endif
    break;
  }

  if (error.Fail())
    socket_up.reset();

  return socket_up;
}

llvm::Expected<Socket::Pair>
Socket::CreatePair(std::optional<SocketProtocol> protocol) {
  constexpr SocketProtocol kBestProtocol =
      LLDB_ENABLE_POSIX ? ProtocolUnixDomain : ProtocolTcp;
  switch (protocol.value_or(kBestProtocol)) {
  case ProtocolTcp:
    return TCPSocket::CreatePair();
#if LLDB_ENABLE_POSIX
  case ProtocolUnixDomain:
  case ProtocolUnixAbstract:
    return DomainSocket::CreatePair();
#endif
  default:
    return llvm::createStringError("unsupported protocol");
  }
}

llvm::Expected<std::unique_ptr<Socket>>
Socket::TcpConnect(llvm::StringRef host_and_port) {
  Log *log = GetLog(LLDBLog::Connection);
  LLDB_LOG(log, "host_and_port = {0}", host_and_port);

  Status error;
  std::unique_ptr<Socket> connect_socket = Create(ProtocolTcp, error);
  if (error.Fail())
    return error.ToError();

  error = connect_socket->Connect(host_and_port);
  if (error.Success())
    return std::move(connect_socket);

  return error.ToError();
}

llvm::Expected<std::unique_ptr<TCPSocket>>
Socket::TcpListen(llvm::StringRef host_and_port, int backlog) {
  Log *log = GetLog(LLDBLog::Connection);
  LLDB_LOG(log, "host_and_port = {0}", host_and_port);

  std::unique_ptr<TCPSocket> listen_socket(
      new TCPSocket(/*should_close=*/true));

  Status error = listen_socket->Listen(host_and_port, backlog);
  if (error.Fail())
    return error.ToError();

  return std::move(listen_socket);
}

llvm::Expected<std::unique_ptr<UDPSocket>>
Socket::UdpConnect(llvm::StringRef host_and_port) {
  return UDPSocket::CreateConnected(host_and_port);
}

llvm::Expected<Socket::HostAndPort>
Socket::DecodeHostAndPort(llvm::StringRef host_and_port) {
  // This regex parses host:port combinations, supporting:
  // - IPv4 sockets (e.g., "127.0.0.1:8080")
  // - IPv6 sockets with host part in square brackets (e.g., "[::1]:80")
  // Group 1: Address (IPv4, hostname, or IPv6 in [])
  // Group 2: Port number (digits only)
  static llvm::Regex g_regex("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+$)");
  HostAndPort ret;
  llvm::SmallVector<llvm::StringRef, 3> matches;
  if (g_regex.match(host_and_port, &matches)) {
    ret.hostname = matches[1].str();
    // IPv6 addresses are wrapped in [] when specified with ports
    if (ret.hostname.front() == '[' && ret.hostname.back() == ']')
      ret.hostname = ret.hostname.substr(1, ret.hostname.size() - 2);
    if (to_integer(matches[2], ret.port, 10))
      return ret;
  }

  return llvm::createStringError(
      llvm::inconvertibleErrorCode(),
      "invalid host:port specification: '%s', both IPv4 (e.g., localhost:8080) "
      "or IPv6 (e.g, [2001:db8::1]:8080) formats are supported",
      host_and_port.str().c_str());
}

IOObject::WaitableHandle Socket::GetWaitableHandle() {
  return (IOObject::WaitableHandle)m_socket;
}

Status Socket::Read(void *buf, size_t &num_bytes) {
  Status error;
  int bytes_received = 0;
  do {
    bytes_received = ::recv(m_socket, static_cast<char *>(buf), num_bytes, 0);
  } while (bytes_received < 0 && IsInterrupted());

  if (bytes_received < 0) {
    SetLastError(error);
    num_bytes = 0;
  } else
    num_bytes = bytes_received;

  LLDB_LOGF(GetLog(LLDBLog::Communication),
            "%p Socket::Read() (socket = %" PRIu64
            ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
            " (error = %s)",
            static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
            static_cast<uint64_t>(num_bytes),
            static_cast<int64_t>(bytes_received), error.AsCString());

  return error;
}

Status Socket::Write(const void *buf, size_t &num_bytes) {
  const size_t src_len = num_bytes;
  Status error;
  int bytes_sent = 0;
  do {
    bytes_sent = Send(buf, num_bytes);
  } while (bytes_sent < 0 && IsInterrupted());

  if (bytes_sent < 0) {
    SetLastError(error);
    num_bytes = 0;
  } else
    num_bytes = bytes_sent;

  LLDB_LOGF(GetLog(LLDBLog::Communication),
            "%p Socket::Write() (socket = %" PRIu64
            ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64
            " (error = %s)",
            static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf,
            static_cast<uint64_t>(src_len), static_cast<int64_t>(bytes_sent),
            error.AsCString());

  return error;
}

Status Socket::Close() {
  Status error;
  if (!IsValid() || !m_should_close_fd)
    return error;

  Log *log = GetLog(LLDBLog::Connection);
  LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")",
            static_cast<void *>(this), static_cast<uint64_t>(m_socket));

  bool success = CloseSocket(m_socket) == 0;
  // A reference to a FD was passed in, set it to an invalid value
  m_socket = kInvalidSocketValue;
  if (!success) {
    SetLastError(error);
  }

  return error;
}

int Socket::GetOption(NativeSocket sockfd, int level, int option_name,
                      int &option_value) {
  get_socket_option_arg_type option_value_p =
      reinterpret_cast<get_socket_option_arg_type>(&option_value);
  socklen_t option_value_size = sizeof(int);
  return ::getsockopt(sockfd, level, option_name, option_value_p,
                      &option_value_size);
}

int Socket::SetOption(NativeSocket sockfd, int level, int option_name,
                      int option_value) {
  set_socket_option_arg_type option_value_p =
      reinterpret_cast<set_socket_option_arg_type>(&option_value);
  return ::setsockopt(sockfd, level, option_name, option_value_p,
                      sizeof(option_value));
}

size_t Socket::Send(const void *buf, const size_t num_bytes) {
  return ::send(m_socket, static_cast<const char *>(buf), num_bytes, 0);
}

void Socket::SetLastError(Status &error) {
#if defined(_WIN32)
  error = Status(::WSAGetLastError(), lldb::eErrorTypeWin32);
#else
  error = Status::FromErrno();
#endif
}

Status Socket::GetLastError() {
  std::error_code EC;
#ifdef _WIN32
  EC = llvm::mapWindowsError(WSAGetLastError());
#else
  EC = std::error_code(errno, std::generic_category());
#endif
  return EC;
}

int Socket::CloseSocket(NativeSocket sockfd) {
#ifdef _WIN32
  return ::closesocket(sockfd);
#else
  return ::close(sockfd);
#endif
}

NativeSocket Socket::CreateSocket(const int domain, const int type,
                                  const int protocol, Status &error) {
  error.Clear();
  auto socket_type = type;
#ifdef SOCK_CLOEXEC
  socket_type |= SOCK_CLOEXEC;
#endif
  auto sock = ::socket(domain, socket_type, protocol);
  if (sock == kInvalidSocketValue)
    SetLastError(error);

  return sock;
}

Status Socket::Accept(const Timeout<std::micro> &timeout, Socket *&socket) {
  socket = nullptr;
  MainLoop accept_loop;
  llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> expected_handles =
      Accept(accept_loop,
             [&accept_loop, &socket](std::unique_ptr<Socket> sock) {
               socket = sock.release();
               accept_loop.RequestTermination();
             });
  if (!expected_handles)
    return Status::FromError(expected_handles.takeError());
  if (timeout) {
    accept_loop.AddCallback(
        [](MainLoopBase &loop) { loop.RequestTermination(); }, *timeout);
  }
  if (Status status = accept_loop.Run(); status.Fail())
    return status;
  if (socket)
    return Status();
  return Status(std::make_error_code(std::errc::timed_out));
}

NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr,
                                  socklen_t *addrlen, Status &error) {
  error.Clear();
#if defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4)
  int flags = SOCK_CLOEXEC;
  NativeSocket fd = llvm::sys::RetryAfterSignal(
      static_cast<NativeSocket>(-1), ::accept4, sockfd, addr, addrlen, flags);
#else
  NativeSocket fd = llvm::sys::RetryAfterSignal(
      static_cast<NativeSocket>(-1), ::accept, sockfd, addr, addrlen);
#endif
  if (fd == kInvalidSocketValue)
    SetLastError(error);
  return fd;
}

llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS,
                                            const Socket::HostAndPort &HP) {
  return OS << '[' << HP.hostname << ']' << ':' << HP.port;
}

std::optional<Socket::ProtocolModePair>
Socket::GetProtocolAndMode(llvm::StringRef scheme) {
  // Keep in sync with ConnectionFileDescriptor::Connect.
  return llvm::StringSwitch<std::optional<ProtocolModePair>>(scheme)
      .Case("listen", ProtocolModePair{SocketProtocol::ProtocolTcp,
                                       SocketMode::ModeAccept})
      .Cases({"accept", "unix-accept"},
             ProtocolModePair{SocketProtocol::ProtocolUnixDomain,
                              SocketMode::ModeAccept})
      .Case("unix-abstract-accept",
            ProtocolModePair{SocketProtocol::ProtocolUnixAbstract,
                             SocketMode::ModeAccept})
      .Cases({"connect", "tcp-connect", "connection"},
             ProtocolModePair{SocketProtocol::ProtocolTcp,
                              SocketMode::ModeConnect})
      .Case("udp", ProtocolModePair{SocketProtocol::ProtocolTcp,
                                    SocketMode::ModeConnect})
      .Case("unix-connect", ProtocolModePair{SocketProtocol::ProtocolUnixDomain,
                                             SocketMode::ModeConnect})
      .Case("unix-abstract-connect",
            ProtocolModePair{SocketProtocol::ProtocolUnixAbstract,
                             SocketMode::ModeConnect})
      .Default(std::nullopt);
}
