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

#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

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

// C++ Includes
#include <algorithm>

// Other libraries and framework includes
#include "llvm/ADT/SmallVector.h"

// Project includes
#include "lldb/Core/Error.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/SelectHelper.h"

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(int fd) { m_fd_map[fd].read_set = true; }

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

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

bool SelectHelper::FDIsSetRead(int 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(int 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(int fd) const {
  auto pos = m_fd_map.find(fd);
  if (pos != m_fd_map.end())
    return pos->second.error_is_set;
  else
    return false;
}

lldb_private::Error SelectHelper::Select() {
  lldb_private::Error error;
#ifdef _MSC_VER
  // 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::Error("Too many file descriptors for select()");
#endif

  int max_read_fd = -1;
  int max_write_fd = -1;
  int max_error_fd = -1;
  int max_fd = -1;
  for (auto &pair : m_fd_map) {
    pair.second.PrepareForSelect();
    const int fd = pair.first;
#if !defined(__APPLE__) && !defined(_MSC_VER)
    lldbassert(fd < FD_SETSIZE);
    if (fd >= FD_SETSIZE) {
      error.SetErrorStringWithFormat("%i is too large for select()", fd);
      return error;
    }
#endif
    if (pair.second.read_set) {
      max_read_fd = std::max<int>(fd, max_read_fd);
      max_fd = std::max<int>(fd, max_fd);
    }
    if (pair.second.write_set) {
      max_write_fd = std::max<int>(fd, max_write_fd);
      max_fd = std::max<int>(fd, max_fd);
    }
    if (pair.second.error_set) {
      max_error_fd = std::max<int>(fd, max_error_fd);
      max_fd = std::max<int>(fd, max_fd);
    }
  }

  if (max_fd == -1) {
    error.SetErrorString("no valid file descriptors");
    return error;
  }

  const int nfds = 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 >= 0) {
    read_fdset.resize((nfds / FD_SETSIZE) + 1);
    read_fdset_ptr = read_fdset.data();
  }
  if (max_write_fd >= 0) {
    write_fdset.resize((nfds / FD_SETSIZE) + 1);
    write_fdset_ptr = write_fdset.data();
  }
  if (max_error_fd >= 0) {
    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 >= 0) {
    FD_ZERO(&read_fdset);
    read_fdset_ptr = &read_fdset;
  }
  if (max_write_fd >= 0) {
    FD_ZERO(&write_fdset);
    write_fdset_ptr = &write_fdset;
  }
  if (max_error_fd >= 0) {
    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 int 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 (1) {
    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;
}
