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

#ifndef QUICHE_QUIC_BINDINGS_QUIC_LIBEVENT_H_
#define QUICHE_QUIC_BINDINGS_QUIC_LIBEVENT_H_

#include <memory>
#include <optional>
#include <utility>

#include "absl/container/flat_hash_set.h"
#include "absl/container/node_hash_map.h"
#include "event2/event.h"
#include "event2/event_struct.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_alarm.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_udp_socket.h"

namespace quic {

// While we inline `struct event` sometimes, it is actually quite large, so
// doing that for the libevent-based QuicAlarm would cause it to not fit into
// the QuicConnectionArena.
struct QUICHE_NO_EXPORT LibeventEventDeleter {
  void operator()(event* ev) { event_free(ev); }
};

// Provides a libevent-based implementation of QuicEventLoop.  Since libevent
// uses relative time for all timeouts, the provided clock does not need to use
// the UNIX time.
class QUICHE_EXPORT LibeventQuicEventLoop : public QuicEventLoop {
 public:
  explicit LibeventQuicEventLoop(event_base* base, QuicClock* clock);
  ~LibeventQuicEventLoop() override;

  // QuicEventLoop implementation.
  bool SupportsEdgeTriggered() const override { return edge_triggered_; }
  std::unique_ptr<QuicAlarmFactory> CreateAlarmFactory() override {
    return std::make_unique<AlarmFactory>(this);
  }
  bool RegisterSocket(QuicUdpSocketFd fd, QuicSocketEventMask events,
                      QuicSocketEventListener* listener) override;
  bool UnregisterSocket(QuicUdpSocketFd fd) override;
  bool RearmSocket(QuicUdpSocketFd fd, QuicSocketEventMask events) override;
  bool ArtificiallyNotifyEvent(QuicUdpSocketFd fd,
                               QuicSocketEventMask events) override;
  void RunEventLoopOnce(QuicTime::Delta default_timeout) override;
  const QuicClock* GetClock() override { return clock_; }

  // Can be called from another thread to wake up the event loop from a blocking
  // RunEventLoopOnce() call.
  void WakeUp() override;
  bool SupportsWakeUp() const override { return true; }

  event_base* base() { return base_; }
  QuicClock* clock() const { return clock_; }

 private:
  void ActivateArtificialEvents();

  class AlarmFactory : public QuicAlarmFactory {
   public:
    AlarmFactory(LibeventQuicEventLoop* loop) : loop_(loop) {}

    // QuicAlarmFactory interface.
    QuicAlarm* CreateAlarm(QuicAlarm::Delegate* delegate) override;
    QuicArenaScopedPtr<QuicAlarm> CreateAlarm(
        QuicArenaScopedPtr<QuicAlarm::Delegate> delegate,
        QuicConnectionArena* arena) override;

   private:
    LibeventQuicEventLoop* loop_;
  };

  class Registration {
   public:
    Registration(LibeventQuicEventLoop* loop, QuicUdpSocketFd fd,
                 QuicSocketEventMask events, QuicSocketEventListener* listener);
    ~Registration();

    void Rearm(QuicSocketEventMask events);

    // Record artificial events that should be notified on the next iteration of
    // the event loop.
    void RecordArtificalEvents(QuicSocketEventMask events);

    // If any artificial events have been recorded, notify the listener about
    // them in the current iteration.
    void MaybeNotifyArtificalEvents();

   private:
    LibeventQuicEventLoop* loop_;
    QuicSocketEventListener* listener_;

    // Used for edge-triggered backends.
    event both_events_;
    // Used for level-triggered backends, since we may have to re-arm read
    // events and write events separately.
    event read_event_;
    event write_event_;

    // Recorded artificial events to be notified on the next iteration.
    QuicSocketEventMask artificial_events_ = 0;
  };

  using RegistrationMap = absl::node_hash_map<QuicUdpSocketFd, Registration>;

  event_base* base_;
  const bool edge_triggered_;
  QuicClock* clock_;

  RegistrationMap registration_map_;
  std::unique_ptr<event, LibeventEventDeleter> artifical_event_timer_;
  absl::flat_hash_set<QuicUdpSocketFd> fds_with_artifical_events_;
};

// RAII-style wrapper around event_base.
class QUICHE_EXPORT LibeventLoop {
 public:
  LibeventLoop(struct event_base* base) : event_base_(base) {}
  ~LibeventLoop() { event_base_free(event_base_); }

  struct event_base* event_base() { return event_base_; }

 private:
  struct event_base* event_base_;
};

// A version of LibeventQuicEventLoop that owns the supplied `event_base`.  Note
// that the inheritance order here matters, since otherwise the `event_base` in
// question will be deleted before the LibeventQuicEventLoop object referencing
// it.
class QUICHE_EXPORT LibeventQuicEventLoopWithOwnership
    : public LibeventLoop,
      public LibeventQuicEventLoop {
 public:
  static std::unique_ptr<LibeventQuicEventLoopWithOwnership> Create(
      QuicClock* clock, bool force_level_triggered = false);

  // Takes ownership of |base|.
  explicit LibeventQuicEventLoopWithOwnership(struct event_base* base,
                                              QuicClock* clock)
      : LibeventLoop(base), LibeventQuicEventLoop(base, clock) {}
};

class QUICHE_EXPORT QuicLibeventEventLoopFactory : public QuicEventLoopFactory {
 public:
  // Provides the preferred libevent backend.
  static QuicLibeventEventLoopFactory* Get() {
    static QuicLibeventEventLoopFactory* factory =
        new QuicLibeventEventLoopFactory(/*force_level_triggered=*/false);
    return factory;
  }

  // Provides the libevent backend that does not support edge-triggered
  // notifications.  Those are useful for tests, since we can test
  // level-triggered I/O even on platforms where edge-triggered is the default.
  static QuicLibeventEventLoopFactory* GetLevelTriggeredBackendForTests() {
    static QuicLibeventEventLoopFactory* factory =
        new QuicLibeventEventLoopFactory(/*force_level_triggered=*/true);
    return factory;
  }

  std::unique_ptr<QuicEventLoop> Create(QuicClock* clock) override {
    return LibeventQuicEventLoopWithOwnership::Create(clock,
                                                      force_level_triggered_);
  }
  std::string GetName() const override { return name_; }

 private:
  explicit QuicLibeventEventLoopFactory(bool force_level_triggered);

  bool force_level_triggered_;
  std::string name_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_BINDINGS_QUIC_LIBEVENT_H_
