#include "private/uds/channel_event_set.h"

#include <log/log.h>

#include <uds/ipc_helper.h>

namespace android {
namespace pdx {
namespace uds {

ChannelEventSet::ChannelEventSet() {
  const int flags = EFD_CLOEXEC | EFD_NONBLOCK;
  LocalHandle epoll_fd, event_fd;

  if (!SetupHandle(epoll_create1(EPOLL_CLOEXEC), &epoll_fd, "epoll") ||
      !SetupHandle(eventfd(0, flags), &event_fd, "event")) {
    return;
  }

  epoll_event event;
  event.events = 0;
  event.data.u32 = 0;
  if (epoll_ctl(epoll_fd.Get(), EPOLL_CTL_ADD, event_fd.Get(), &event) < 0) {
    const int error = errno;
    ALOGE("ChannelEventSet::ChannelEventSet: Failed to add event_fd: %s",
          strerror(error));
    return;
  }

  epoll_fd_ = std::move(epoll_fd);
  event_fd_ = std::move(event_fd);
}

Status<void> ChannelEventSet::AddDataFd(const LocalHandle& data_fd) {
  epoll_event event;
  event.events = EPOLLHUP | EPOLLRDHUP;
  event.data.u32 = event.events;
  if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_ADD, data_fd.Get(), &event) < 0) {
    const int error = errno;
    ALOGE("ChannelEventSet::ChannelEventSet: Failed to add event_fd: %s",
          strerror(error));
    return ErrorStatus{error};
  } else {
    return {};
  }
}

int ChannelEventSet::ModifyEvents(int clear_mask, int set_mask) {
  ALOGD_IF(TRACE, "ChannelEventSet::ModifyEvents: clear_mask=%x set_mask=%x",
           clear_mask, set_mask);
  const int old_bits = event_bits_;
  const int new_bits = (event_bits_ & ~clear_mask) | set_mask;
  event_bits_ = new_bits;

  // If anything changed clear the event and update the event mask.
  if (old_bits != new_bits) {
    eventfd_t value;
    eventfd_read(event_fd_.Get(), &value);

    epoll_event event;
    event.events = POLLIN;
    event.data.u32 = event_bits_;
    if (epoll_ctl(epoll_fd_.Get(), EPOLL_CTL_MOD, event_fd_.Get(), &event) <
        0) {
      const int error = errno;
      ALOGE("ChannelEventSet::AddEventHandle: Failed to update event: %s",
            strerror(error));
      return -error;
    }
  }

  // If there are any bits set, re-trigger the eventfd.
  if (new_bits)
    eventfd_write(event_fd_.Get(), 1);

  return 0;
}

Status<void> ChannelEventSet::SetupHandle(int fd, LocalHandle* handle,
                                          const char* error_name) {
  const int error = errno;
  handle->Reset(fd);
  if (!*handle) {
    ALOGE("ChannelEventSet::SetupHandle: Failed to setup %s handle: %s",
          error_name, strerror(error));
    return ErrorStatus{error};
  }
  return {};
}

Status<int> ChannelEventReceiver::GetPendingEvents() const {
  constexpr long kTimeoutMs = 0;
  epoll_event event;
  const int count =
      RETRY_EINTR(epoll_wait(epoll_fd_.Get(), &event, 1, kTimeoutMs));

  Status<int> status;
  if (count < 0) {
    status.SetError(errno);
    ALOGE("ChannelEventReceiver::GetPendingEvents: Failed to get events: %s",
          status.GetErrorMessage().c_str());
    return status;
  } else if (count == 0) {
    status.SetError(ETIMEDOUT);
    return status;
  }

  const int mask_out = event.data.u32;
  ALOGD_IF(TRACE, "ChannelEventReceiver::GetPendingEvents: mask_out=%x",
           mask_out);

  status.SetValue(mask_out);
  return status;
}

}  // namespace uds
}  // namespace pdx
}  // namespace android
