// Copyright 2022 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/quic/bindings/quic_libevent.h"

#include <memory>

#include "absl/time/time.h"
#include "event2/event.h"
#include "event2/event_struct.h"
#include "event2/thread.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_alarm.h"
#include "quiche/quic/core/quic_clock.h"
#include "quiche/quic/core/quic_default_clock.h"
#include "quiche/quic/core/quic_time.h"

namespace quic {

using LibeventEventMask = short;  // NOLINT(runtime/int)

QuicSocketEventMask LibeventEventMaskToQuicEvents(int events) {
  return ((events & EV_READ) ? kSocketEventReadable : 0) |
         ((events & EV_WRITE) ? kSocketEventWritable : 0);
}

LibeventEventMask QuicEventsToLibeventEventMask(QuicSocketEventMask events) {
  return ((events & kSocketEventReadable) ? EV_READ : 0) |
         ((events & kSocketEventWritable) ? EV_WRITE : 0);
}

class LibeventAlarm : public QuicAlarm {
 public:
  LibeventAlarm(LibeventQuicEventLoop* loop,
                QuicArenaScopedPtr<QuicAlarm::Delegate> delegate)
      : QuicAlarm(std::move(delegate)), clock_(loop->clock()) {
    event_.reset(evtimer_new(
        loop->base(),
        [](evutil_socket_t, LibeventEventMask, void* arg) {
          LibeventAlarm* self = reinterpret_cast<LibeventAlarm*>(arg);
          self->Fire();
        },
        this));
  }

 protected:
  void SetImpl() override {
    absl::Duration timeout =
        absl::Microseconds((deadline() - clock_->Now()).ToMicroseconds());
    timeval unix_time = absl::ToTimeval(timeout);
    event_add(event_.get(), &unix_time);
  }

  void CancelImpl() override { event_del(event_.get()); }

 private:
  // While we inline `struct event` elsewhere, it is actually quite large, so
  // doing that for the libevent-based QuicAlarm would cause it to not fit into
  // the QuicConnectionArena.
  struct EventDeleter {
    void operator()(event* ev) { event_free(ev); }
  };
  std::unique_ptr<event, EventDeleter> event_;
  QuicClock* clock_;
};

LibeventQuicEventLoop::LibeventQuicEventLoop(event_base* base, QuicClock* clock)
    : base_(base),
      edge_triggered_(event_base_get_features(base) & EV_FEATURE_ET),
      clock_(clock) {
  QUICHE_CHECK_LE(sizeof(event), event_get_struct_event_size())
      << "libevent ABI mismatch: sizeof(event) is bigger than the one QUICHE "
         "has been compiled with";
}

bool LibeventQuicEventLoop::RegisterSocket(QuicUdpSocketFd fd,
                                           QuicSocketEventMask events,
                                           QuicSocketEventListener* listener) {
  auto [it, success] =
      registration_map_.try_emplace(fd, this, fd, events, listener);
  return success;
}

bool LibeventQuicEventLoop::UnregisterSocket(QuicUdpSocketFd fd) {
  return registration_map_.erase(fd);
}

bool LibeventQuicEventLoop::RearmSocket(QuicUdpSocketFd fd,
                                        QuicSocketEventMask events) {
  if (edge_triggered_) {
    QUICHE_BUG(LibeventQuicEventLoop_RearmSocket_called_on_ET)
        << "RearmSocket() called on an edge-triggered event loop";
    return false;
  }
  auto it = registration_map_.find(fd);
  if (it == registration_map_.end()) {
    return false;
  }
  it->second.Rearm(events);
  return true;
}

bool LibeventQuicEventLoop::ArtificiallyNotifyEvent(
    QuicUdpSocketFd fd, QuicSocketEventMask events) {
  auto it = registration_map_.find(fd);
  if (it == registration_map_.end()) {
    return false;
  }
  it->second.ArtificiallyNotify(events);
  return true;
}

void LibeventQuicEventLoop::RunEventLoopOnce(QuicTime::Delta default_timeout) {
  timeval timeout =
      absl::ToTimeval(absl::Microseconds(default_timeout.ToMicroseconds()));
  event_base_loopexit(base_, &timeout);
  event_base_loop(base_, EVLOOP_ONCE);
}

void LibeventQuicEventLoop::WakeUp() {
  timeval timeout = absl::ToTimeval(absl::ZeroDuration());
  event_base_loopexit(base_, &timeout);
}

LibeventQuicEventLoop::Registration::Registration(
    LibeventQuicEventLoop* loop, QuicUdpSocketFd fd, QuicSocketEventMask events,
    QuicSocketEventListener* listener)
    : loop_(loop), listener_(listener) {
  event_callback_fn callback = [](evutil_socket_t fd, LibeventEventMask events,
                                  void* arg) {
    auto* self = reinterpret_cast<LibeventQuicEventLoop::Registration*>(arg);
    self->listener_->OnSocketEvent(self->loop_, fd,
                                   LibeventEventMaskToQuicEvents(events));
  };

  if (loop_->SupportsEdgeTriggered()) {
    LibeventEventMask mask =
        QuicEventsToLibeventEventMask(events) | EV_PERSIST | EV_ET;
    event_assign(&both_events_, loop_->base(), fd, mask, callback, this);
    event_add(&both_events_, nullptr);
  } else {
    event_assign(&read_event_, loop_->base(), fd, EV_READ, callback, this);
    event_assign(&write_event_, loop_->base(), fd, EV_WRITE, callback, this);
    Rearm(events);
  }
}

LibeventQuicEventLoop::Registration::~Registration() {
  if (loop_->SupportsEdgeTriggered()) {
    event_del(&both_events_);
  } else {
    event_del(&read_event_);
    event_del(&write_event_);
  }
}

void LibeventQuicEventLoop::Registration::ArtificiallyNotify(
    QuicSocketEventMask events) {
  if (loop_->SupportsEdgeTriggered()) {
    event_active(&both_events_, QuicEventsToLibeventEventMask(events), 0);
    return;
  }

  if (events & kSocketEventReadable) {
    event_active(&read_event_, EV_READ, 0);
  }
  if (events & kSocketEventWritable) {
    event_active(&write_event_, EV_WRITE, 0);
  }
}

void LibeventQuicEventLoop::Registration::Rearm(QuicSocketEventMask events) {
  QUICHE_DCHECK(!loop_->SupportsEdgeTriggered());
  if (events & kSocketEventReadable) {
    event_add(&read_event_, nullptr);
  }
  if (events & kSocketEventWritable) {
    event_add(&write_event_, nullptr);
  }
}

QuicAlarm* LibeventQuicEventLoop::AlarmFactory::CreateAlarm(
    QuicAlarm::Delegate* delegate) {
  return new LibeventAlarm(loop_,
                           QuicArenaScopedPtr<QuicAlarm::Delegate>(delegate));
}

QuicArenaScopedPtr<QuicAlarm> LibeventQuicEventLoop::AlarmFactory::CreateAlarm(
    QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
    QuicConnectionArena* arena) {
  if (arena != nullptr) {
    return arena->New<LibeventAlarm>(loop_, std::move(delegate));
  }
  return QuicArenaScopedPtr<QuicAlarm>(
      new LibeventAlarm(loop_, std::move(delegate)));
}

QuicLibeventEventLoopFactory::QuicLibeventEventLoopFactory(
    bool force_level_triggered)
    : force_level_triggered_(force_level_triggered) {
  std::unique_ptr<QuicEventLoop> event_loop = Create(QuicDefaultClock::Get());
  name_ = absl::StrFormat(
      "libevent(%s)",
      event_base_get_method(
          static_cast<LibeventQuicEventLoopWithOwnership*>(event_loop.get())
              ->base()));
}

struct LibeventConfigDeleter {
  void operator()(event_config* config) { event_config_free(config); }
};

std::unique_ptr<LibeventQuicEventLoopWithOwnership>
LibeventQuicEventLoopWithOwnership::Create(QuicClock* clock,
                                           bool force_level_triggered) {
  // Required for event_base_loopbreak() to actually work.
  static int threads_initialized = []() {
#ifdef _WIN32
    return evthread_use_windows_threads();
#else
    return evthread_use_pthreads();
#endif
  }();
  QUICHE_DCHECK_EQ(threads_initialized, 0);

  std::unique_ptr<event_config, LibeventConfigDeleter> config(
      event_config_new());
  if (force_level_triggered) {
    // epoll and kqueue are the two only current libevent backends that support
    // edge-triggered I/O.
    event_config_avoid_method(config.get(), "epoll");
    event_config_avoid_method(config.get(), "kqueue");
  }
  return std::make_unique<LibeventQuicEventLoopWithOwnership>(
      event_base_new_with_config(config.get()), clock);
}

}  // namespace quic
