#include "epoll_event_dispatcher.h"

#include <log/log.h>
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/prctl.h>

#include <dvr/performance_client_api.h>

namespace android {
namespace dvr {

EpollEventDispatcher::EpollEventDispatcher() {
  epoll_fd_.Reset(epoll_create(64));
  if (!epoll_fd_) {
    ALOGE("Failed to create epoll fd: %s", strerror(errno));
    return;
  }

  event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
  if (!event_fd_) {
    ALOGE("Failed to create event for epolling: %s", strerror(errno));
    return;
  }

  // Add watch for eventfd. This should only watch for EPOLLIN, which gets set
  // when eventfd_write occurs. Use "this" as a unique sentinal value to
  // identify events from the event fd.
  epoll_event event = {.events = EPOLLIN, .data = {.ptr = this}};
  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, event_fd_.Get(), &event) < 0) {
    ALOGE("Failed to add eventfd to epoll set because: %s", strerror(errno));
    return;
  }

  thread_ = std::thread(&EpollEventDispatcher::EventThread, this);
}

EpollEventDispatcher::~EpollEventDispatcher() { Stop(); }

void EpollEventDispatcher::Stop() {
  exit_thread_.store(true);
  eventfd_write(event_fd_.Get(), 1);
}

pdx::Status<void> EpollEventDispatcher::AddEventHandler(int fd, int event_mask,
                                                        Handler handler) {
  std::lock_guard<std::mutex> lock(lock_);

  epoll_event event;
  event.events = event_mask;
  event.data.ptr = &(handlers_[fd] = handler);

  ALOGD_IF(
      TRACE,
      "EpollEventDispatcher::AddEventHandler: fd=%d event_mask=0x%x handler=%p",
      fd, event_mask, event.data.ptr);

  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, fd, &event) < 0) {
    const int error = errno;
    ALOGE("Failed to add fd to epoll set because: %s", strerror(error));
    return pdx::ErrorStatus(error);
  } else {
    return {};
  }
}

pdx::Status<void> EpollEventDispatcher::RemoveEventHandler(int fd) {
  ALOGD_IF(TRACE, "EpollEventDispatcher::RemoveEventHandler: fd=%d", fd);
  std::lock_guard<std::mutex> lock(lock_);

  epoll_event dummy;  // See BUGS in man 2 epoll_ctl.
  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_DEL, fd, &dummy) < 0) {
    const int error = errno;
    ALOGE("Failed to remove fd from epoll set because: %s", strerror(error));
    return pdx::ErrorStatus(error);
  }

  // If the fd was valid above, add it to the list of ids to remove.
  removed_handlers_.push_back(fd);

  // Wake up the event thread to clean up.
  eventfd_write(event_fd_.Get(), 1);

  return {};
}

void EpollEventDispatcher::EventThread() {
  prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrEvent"), 0, 0, 0);

  const int error = dvrSetSchedulerClass(0, "graphics");
  LOG_ALWAYS_FATAL_IF(
      error < 0,
      "EpollEventDispatcher::EventThread: Failed to set scheduler class: %s",
      strerror(-error));

  const size_t kMaxNumEvents = 128;
  epoll_event events[kMaxNumEvents];

  while (!exit_thread_.load()) {
    const int num_events = epoll_wait(epoll_fd_.Get(), events, kMaxNumEvents, -1);
    if (num_events < 0 && errno != EINTR)
      break;

    ALOGD_IF(TRACE > 1, "EpollEventDispatcher::EventThread: num_events=%d",
             num_events);

    for (int i = 0; i < num_events; i++) {
      ALOGD_IF(
          TRACE > 1,
          "EpollEventDispatcher::EventThread: event %d: handler=%p events=0x%x",
          i, events[i].data.ptr, events[i].events);

      if (events[i].data.ptr == this) {
        // Clear pending event on event_fd_. Serialize the read with respect to
        // writes from other threads.
        std::lock_guard<std::mutex> lock(lock_);
        eventfd_t value;
        eventfd_read(event_fd_.Get(), &value);
      } else {
        auto handler = reinterpret_cast<Handler*>(events[i].data.ptr);
        if (handler)
          (*handler)(events[i].events);
      }
    }

    // Remove any handlers that have been posted for removal. This is done here
    // instead of in RemoveEventHandler() to prevent races between the dispatch
    // thread and the code requesting the removal. Handlers are guaranteed to
    // stay alive between exiting epoll_wait() and the dispatch loop above.
    std::lock_guard<std::mutex> lock(lock_);
    for (auto handler_fd : removed_handlers_) {
      ALOGD_IF(TRACE,
               "EpollEventDispatcher::EventThread: removing handler: fd=%d",
               handler_fd);
      handlers_.erase(handler_fd);
    }
    removed_handlers_.clear();
  }
}

}  // namespace dvr
}  // namespace android
