//===-- SelectHelper.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
//
//===----------------------------------------------------------------------===//

#if defined(__APPLE__)
// Enable this special support for Apple builds where we can have unlimited
// select bounds. We tried switching to poll() and kqueue and we were panicing
// the kernel, so we have to stick with select for now.
#define _DARWIN_UNLIMITED_SELECT
#endif

#include "lldb/Utility/SelectHelper.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Status.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-types.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Optional.h"

#include <algorithm>
#include <chrono>

#include <cerrno>
#if defined(_WIN32)
// Define NOMINMAX to avoid macros that conflict with std::min and std::max
#define NOMINMAX
#include <winsock2.h>
#else
#include <sys/time.h>
#include <sys/select.h>
#endif


SelectHelper::SelectHelper()
    : m_fd_map(), m_end_time() // Infinite timeout unless
                               // SelectHelper::SetTimeout() gets called
{}

void SelectHelper::SetTimeout(const std::chrono::microseconds &timeout) {
  using namespace std::chrono;
  m_end_time = steady_clock::time_point(steady_clock::now() + timeout);
}

void SelectHelper::FDSetRead(lldb::socket_t fd) {
  m_fd_map[fd].read_set = true;
}

void SelectHelper::FDSetWrite(lldb::socket_t fd) {
  m_fd_map[fd].write_set = true;
}

void SelectHelper::FDSetError(lldb::socket_t fd) {
  m_fd_map[fd].error_set = true;
}

bool SelectHelper::FDIsSetRead(lldb::socket_t fd) const {
  auto pos = m_fd_map.find(fd);
  if (pos != m_fd_map.end())
    return pos->second.read_is_set;
  else
    return false;
}

bool SelectHelper::FDIsSetWrite(lldb::socket_t fd) const {
  auto pos = m_fd_map.find(fd);
  if (pos != m_fd_map.end())
    return pos->second.write_is_set;
  else
    return false;
}

bool SelectHelper::FDIsSetError(lldb::socket_t fd) const {
  auto pos = m_fd_map.find(fd);
  if (pos != m_fd_map.end())
    return pos->second.error_is_set;
  else
    return false;
}

static void updateMaxFd(llvm::Optional<lldb::socket_t> &vold,
                        lldb::socket_t vnew) {
  if (!vold.hasValue())
    vold = vnew;
  else
    vold = std::max(*vold, vnew);
}

lldb_private::Status SelectHelper::Select() {
  lldb_private::Status error;
#ifdef _WIN32
  // On windows FD_SETSIZE limits the number of file descriptors, not their
  // numeric value.
  lldbassert(m_fd_map.size() <= FD_SETSIZE);
  if (m_fd_map.size() > FD_SETSIZE)
    return lldb_private::Status("Too many file descriptors for select()");
#endif

  llvm::Optional<lldb::socket_t> max_read_fd;
  llvm::Optional<lldb::socket_t> max_write_fd;
  llvm::Optional<lldb::socket_t> max_error_fd;
  llvm::Optional<lldb::socket_t> max_fd;
  for (auto &pair : m_fd_map) {
    pair.second.PrepareForSelect();
    const lldb::socket_t fd = pair.first;
#if !defined(__APPLE__) && !defined(_WIN32)
    lldbassert(fd < static_cast<int>(FD_SETSIZE));
    if (fd >= static_cast<int>(FD_SETSIZE)) {
      error.SetErrorStringWithFormat("%i is too large for select()", fd);
      return error;
    }
#endif
    if (pair.second.read_set)
      updateMaxFd(max_read_fd, fd);
    if (pair.second.write_set)
      updateMaxFd(max_write_fd, fd);
    if (pair.second.error_set)
      updateMaxFd(max_error_fd, fd);
    updateMaxFd(max_fd, fd);
  }

  if (!max_fd.hasValue()) {
    error.SetErrorString("no valid file descriptors");
    return error;
  }

  const unsigned nfds = static_cast<unsigned>(*max_fd) + 1;
  fd_set *read_fdset_ptr = nullptr;
  fd_set *write_fdset_ptr = nullptr;
  fd_set *error_fdset_ptr = nullptr;
// Initialize and zero out the fdsets
#if defined(__APPLE__)
  llvm::SmallVector<fd_set, 1> read_fdset;
  llvm::SmallVector<fd_set, 1> write_fdset;
  llvm::SmallVector<fd_set, 1> error_fdset;

  if (max_read_fd.hasValue()) {
    read_fdset.resize((nfds / FD_SETSIZE) + 1);
    read_fdset_ptr = read_fdset.data();
  }
  if (max_write_fd.hasValue()) {
    write_fdset.resize((nfds / FD_SETSIZE) + 1);
    write_fdset_ptr = write_fdset.data();
  }
  if (max_error_fd.hasValue()) {
    error_fdset.resize((nfds / FD_SETSIZE) + 1);
    error_fdset_ptr = error_fdset.data();
  }
  for (auto &fd_set : read_fdset)
    FD_ZERO(&fd_set);
  for (auto &fd_set : write_fdset)
    FD_ZERO(&fd_set);
  for (auto &fd_set : error_fdset)
    FD_ZERO(&fd_set);
#else
  fd_set read_fdset;
  fd_set write_fdset;
  fd_set error_fdset;

  if (max_read_fd.hasValue()) {
    FD_ZERO(&read_fdset);
    read_fdset_ptr = &read_fdset;
  }
  if (max_write_fd.hasValue()) {
    FD_ZERO(&write_fdset);
    write_fdset_ptr = &write_fdset;
  }
  if (max_error_fd.hasValue()) {
    FD_ZERO(&error_fdset);
    error_fdset_ptr = &error_fdset;
  }
#endif
  // Set the FD bits in the fdsets for read/write/error
  for (auto &pair : m_fd_map) {
    const lldb::socket_t fd = pair.first;

    if (pair.second.read_set)
      FD_SET(fd, read_fdset_ptr);

    if (pair.second.write_set)
      FD_SET(fd, write_fdset_ptr);

    if (pair.second.error_set)
      FD_SET(fd, error_fdset_ptr);
  }

  // Setup our timeout time value if needed
  struct timeval *tv_ptr = nullptr;
  struct timeval tv = {0, 0};

  while (true) {
    using namespace std::chrono;
    // Setup out relative timeout based on the end time if we have one
    if (m_end_time.hasValue()) {
      tv_ptr = &tv;
      const auto remaining_dur = duration_cast<microseconds>(
          m_end_time.getValue() - steady_clock::now());
      if (remaining_dur.count() > 0) {
        // Wait for a specific amount of time
        const auto dur_secs = duration_cast<seconds>(remaining_dur);
        const auto dur_usecs = remaining_dur % seconds(1);
        tv.tv_sec = dur_secs.count();
        tv.tv_usec = dur_usecs.count();
      } else {
        // Just poll once with no timeout
        tv.tv_sec = 0;
        tv.tv_usec = 0;
      }
    }
    const int num_set_fds = ::select(nfds, read_fdset_ptr, write_fdset_ptr,
                                     error_fdset_ptr, tv_ptr);
    if (num_set_fds < 0) {
      // We got an error
      error.SetErrorToErrno();
      if (error.GetError() == EINTR) {
        error.Clear();
        continue; // Keep calling select if we get EINTR
      } else
        return error;
    } else if (num_set_fds == 0) {
      // Timeout
      error.SetError(ETIMEDOUT, lldb::eErrorTypePOSIX);
      error.SetErrorString("timed out");
      return error;
    } else {
      // One or more descriptors were set, update the FDInfo::select_is_set
      // mask so users can ask the SelectHelper class so clients can call one
      // of:

      for (auto &pair : m_fd_map) {
        const int fd = pair.first;

        if (pair.second.read_set) {
          if (FD_ISSET(fd, read_fdset_ptr))
            pair.second.read_is_set = true;
        }
        if (pair.second.write_set) {
          if (FD_ISSET(fd, write_fdset_ptr))
            pair.second.write_is_set = true;
        }
        if (pair.second.error_set) {
          if (FD_ISSET(fd, error_fdset_ptr))
            pair.second.error_is_set = true;
        }
      }
      break;
    }
  }
  return error;
}
