//===-- Broadcaster.h -------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_UTILITY_BROADCASTER_H
#define LLDB_UTILITY_BROADCASTER_H

#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-defines.h"
#include "lldb/lldb-forward.h"

#include "llvm/ADT/SmallVector.h"

#include <cstdint>
#include <map>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <utility>
#include <vector>

namespace lldb_private {
class Broadcaster;
class EventData;
class Listener;
class Stream;
} // namespace lldb_private

namespace lldb_private {

/// lldb::BroadcastEventSpec
///
/// This class is used to specify a kind of event to register for.  The
/// Debugger maintains a list of BroadcastEventSpec's and when it is made
class BroadcastEventSpec {
public:
  BroadcastEventSpec(ConstString broadcaster_class, uint32_t event_bits)
      : m_broadcaster_class(broadcaster_class), m_event_bits(event_bits) {}

  ~BroadcastEventSpec() = default;

  ConstString GetBroadcasterClass() const { return m_broadcaster_class; }

  uint32_t GetEventBits() const { return m_event_bits; }

  /// Tell whether this BroadcastEventSpec is contained in in_spec. That is:
  /// (a) the two spec's share the same broadcaster class (b) the event bits of
  /// this spec are wholly contained in those of in_spec.
  bool IsContainedIn(const BroadcastEventSpec &in_spec) const {
    if (m_broadcaster_class != in_spec.GetBroadcasterClass())
      return false;
    uint32_t in_bits = in_spec.GetEventBits();
    if (in_bits == m_event_bits)
      return true;

    if ((m_event_bits & in_bits) != 0 && (m_event_bits & ~in_bits) == 0)
      return true;

    return false;
  }

  bool operator<(const BroadcastEventSpec &rhs) const;

private:
  ConstString m_broadcaster_class;
  uint32_t m_event_bits;
};

class BroadcasterManager
    : public std::enable_shared_from_this<BroadcasterManager> {
public:
  friend class Listener;

protected:
  BroadcasterManager();

public:
  /// Listeners hold onto weak pointers to their broadcaster managers.  So they
  /// must be made into shared pointers, which you do with
  /// MakeBroadcasterManager.
  static lldb::BroadcasterManagerSP MakeBroadcasterManager();

  ~BroadcasterManager() = default;

  uint32_t RegisterListenerForEvents(const lldb::ListenerSP &listener_sp,
                                     const BroadcastEventSpec &event_spec);

  bool UnregisterListenerForEvents(const lldb::ListenerSP &listener_sp,
                                   const BroadcastEventSpec &event_spec);

  lldb::ListenerSP
  GetListenerForEventSpec(const BroadcastEventSpec &event_spec) const;

  void SignUpListenersForBroadcaster(Broadcaster &broadcaster);

  void RemoveListener(const lldb::ListenerSP &listener_sp);

  void RemoveListener(Listener *listener);

  void Clear();

private:
  typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key;
  typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection;
  typedef std::set<lldb::ListenerSP> listener_collection;
  collection m_event_map;
  listener_collection m_listeners;

  mutable std::recursive_mutex m_manager_mutex;

  // A couple of comparator classes for find_if:

  class BroadcasterClassMatches {
  public:
    BroadcasterClassMatches(ConstString broadcaster_class)
        : m_broadcaster_class(broadcaster_class) {}

    ~BroadcasterClassMatches() = default;

    bool operator()(const event_listener_key &input) const {
      return (input.first.GetBroadcasterClass() == m_broadcaster_class);
    }

  private:
    ConstString m_broadcaster_class;
  };

  class BroadcastEventSpecMatches {
  public:
    BroadcastEventSpecMatches(const BroadcastEventSpec &broadcaster_spec)
        : m_broadcaster_spec(broadcaster_spec) {}

    ~BroadcastEventSpecMatches() = default;

    bool operator()(const event_listener_key &input) const {
      return (input.first.IsContainedIn(m_broadcaster_spec));
    }

  private:
    BroadcastEventSpec m_broadcaster_spec;
  };

  class ListenerMatchesAndSharedBits {
  public:
    explicit ListenerMatchesAndSharedBits(
        const BroadcastEventSpec &broadcaster_spec,
        const lldb::ListenerSP &listener_sp)
        : m_broadcaster_spec(broadcaster_spec), m_listener_sp(listener_sp) {}

    ~ListenerMatchesAndSharedBits() = default;

    bool operator()(const event_listener_key &input) const {
      return (input.first.GetBroadcasterClass() ==
                  m_broadcaster_spec.GetBroadcasterClass() &&
              (input.first.GetEventBits() &
               m_broadcaster_spec.GetEventBits()) != 0 &&
              input.second == m_listener_sp);
    }

  private:
    BroadcastEventSpec m_broadcaster_spec;
    const lldb::ListenerSP m_listener_sp;
  };

  class ListenerMatches {
  public:
    explicit ListenerMatches(const lldb::ListenerSP &in_listener_sp)
        : m_listener_sp(in_listener_sp) {}

    ~ListenerMatches() = default;

    bool operator()(const event_listener_key &input) const {
      if (input.second == m_listener_sp)
        return true;

      return false;
    }

  private:
    const lldb::ListenerSP m_listener_sp;
  };

  class ListenerMatchesPointer {
  public:
    ListenerMatchesPointer(const Listener *in_listener)
        : m_listener(in_listener) {}

    ~ListenerMatchesPointer() = default;

    bool operator()(const event_listener_key &input) const {
      if (input.second.get() == m_listener)
        return true;

      return false;
    }

    bool operator()(const lldb::ListenerSP &input) const {
      if (input.get() == m_listener)
        return true;

      return false;
    }

  private:
    const Listener *m_listener;
  };
};

/// \class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event
/// broadcasting class.
///
/// The Broadcaster class is designed to be subclassed by objects that wish to
/// vend events in a multi-threaded environment. Broadcaster objects can each
/// vend 32 events. Each event is represented by a bit in a 32 bit value and
/// these bits can be set:
///     \see Broadcaster::SetEventBits(uint32_t)
/// or cleared:
///     \see Broadcaster::ResetEventBits(uint32_t)
/// When an event gets set the Broadcaster object will notify the Listener
/// object that is listening for the event (if there is one).
///
/// Subclasses should provide broadcast bit definitions for any events they
/// vend, typically using an enumeration:
///     \code
///         class Foo : public Broadcaster
///         {
///         public:
///         // Broadcaster event bits definitions.
///         enum
///         {
///             eBroadcastBitOne   = (1 << 0),
///             eBroadcastBitTwo   = (1 << 1),
///             eBroadcastBitThree = (1 << 2),
///             ...
///         };
///     \endcode
class Broadcaster {
  friend class Listener;
  friend class Event;

public:
  /// Construct with a broadcaster with a name.
  ///
  /// \param[in] name
  ///     A NULL terminated C string that contains the name of the
  ///     broadcaster object.
  Broadcaster(lldb::BroadcasterManagerSP manager_sp, const char *name);

  /// Destructor.
  ///
  /// The destructor is virtual since this class gets subclassed.
  virtual ~Broadcaster();

  void CheckInWithManager();

  /// Broadcast an event which has no associated data.
  void BroadcastEvent(lldb::EventSP &event_sp) {
    m_broadcaster_sp->BroadcastEvent(event_sp);
  }

  void BroadcastEventIfUnique(lldb::EventSP &event_sp) {
    m_broadcaster_sp->BroadcastEventIfUnique(event_sp);
  }

  void BroadcastEvent(uint32_t event_type,
                      const lldb::EventDataSP &event_data_sp) {
    m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp);
  }

  void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) {
    m_broadcaster_sp->BroadcastEvent(event_type, event_data);
  }

  void BroadcastEventIfUnique(uint32_t event_type,
                              EventData *event_data = nullptr) {
    m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data);
  }

  void Clear() { m_broadcaster_sp->Clear(); }

  virtual void AddInitialEventsToListener(const lldb::ListenerSP &listener_sp,
                                          uint32_t requested_events);

  /// Listen for any events specified by \a event_mask.
  ///
  /// Only one listener can listen to each event bit in a given Broadcaster.
  /// Once a listener has acquired an event bit, no other broadcaster will
  /// have access to it until it is relinquished by the first listener that
  /// gets it. The actual event bits that get acquired by \a listener may be
  /// different from what is requested in \a event_mask, and to track this the
  /// actual event bits that are acquired get returned.
  ///
  /// \param[in] listener_sp
  ///     The Listener object that wants to monitor the events that
  ///     get broadcast by this object.
  ///
  /// \param[in] event_mask
  ///     A bit mask that indicates which events the listener is
  ///     asking to monitor.
  ///
  /// \return
  ///     The actual event bits that were acquired by \a listener.
  uint32_t AddListener(const lldb::ListenerSP &listener_sp,
                       uint32_t event_mask) {
    return m_broadcaster_sp->AddListener(listener_sp, event_mask);
  }

  /// Get the NULL terminated C string name of this Broadcaster object.
  ///
  /// \return
  ///     The NULL terminated C string name of this Broadcaster.
  ConstString GetBroadcasterName() { return m_broadcaster_name; }

  /// Get the event name(s) for one or more event bits.
  ///
  /// \param[in] event_mask
  ///     A bit mask that indicates which events to get names for.
  ///
  /// \return
  ///     The NULL terminated C string name of this Broadcaster.
  bool GetEventNames(Stream &s, const uint32_t event_mask,
                     bool prefix_with_broadcaster_name) const {
    return m_broadcaster_sp->GetEventNames(s, event_mask,
                                           prefix_with_broadcaster_name);
  }

  /// Set the name for an event bit.
  ///
  /// \param[in] event_mask
  ///     A bit mask that indicates which events the listener is
  ///     asking to monitor.
  void SetEventName(uint32_t event_mask, const char *name) {
    m_broadcaster_sp->SetEventName(event_mask, name);
  }

  const char *GetEventName(uint32_t event_mask) const {
    return m_broadcaster_sp->GetEventName(event_mask);
  }

  bool EventTypeHasListeners(uint32_t event_type) {
    return m_broadcaster_sp->EventTypeHasListeners(event_type);
  }

  /// Removes a Listener from this broadcasters list and frees the event bits
  /// specified by \a event_mask that were previously acquired by \a listener
  /// (assuming \a listener was listening to this object) for other listener
  /// objects to use.
  ///
  /// \param[in] listener_sp
  ///     A Listener object that previously called AddListener.
  ///
  /// \param[in] event_mask
  ///     The event bits \a listener wishes to relinquish.
  ///
  /// \return
  ///     \b True if the listener was listening to this broadcaster
  ///     and was removed, \b false otherwise.
  ///
  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
  bool RemoveListener(const lldb::ListenerSP &listener_sp,
                      uint32_t event_mask = UINT32_MAX) {
    return m_broadcaster_sp->RemoveListener(listener_sp, event_mask);
  }

  /// Provides a simple mechanism to temporarily redirect events from
  /// broadcaster.  When you call this function passing in a listener and
  /// event type mask, all events from the broadcaster matching the mask will
  /// now go to the hijacking listener. Only one hijack can occur at a time.
  /// If we need more than this we will have to implement a Listener stack.
  ///
  /// \param[in] listener_sp
  ///     A Listener object.  You do not need to call StartListeningForEvents
  ///     for this broadcaster (that would fail anyway since the event bits
  ///     would most likely be taken by the listener(s) you are usurping.
  ///
  /// \param[in] event_mask
  ///     The event bits \a listener wishes to hijack.
  ///
  /// \return
  ///     \b True if the event mask could be hijacked, \b false otherwise.
  ///
  /// \see uint32_t Broadcaster::AddListener (Listener*, uint32_t)
  bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
                         uint32_t event_mask = UINT32_MAX) {
    return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask);
  }

  bool IsHijackedForEvent(uint32_t event_mask) {
    return m_broadcaster_sp->IsHijackedForEvent(event_mask);
  }

  /// Restore the state of the Broadcaster from a previous hijack attempt.
  void RestoreBroadcaster() { m_broadcaster_sp->RestoreBroadcaster(); }

  /// This needs to be filled in if you are going to register the broadcaster
  /// with the broadcaster manager and do broadcaster class matching.
  /// FIXME: Probably should make a ManagedBroadcaster subclass with all the
  /// bits needed to work with the BroadcasterManager, so that it is clearer
  /// how to add one.
  virtual ConstString &GetBroadcasterClass() const;

  lldb::BroadcasterManagerSP GetManager();

protected:
  /// BroadcasterImpl contains the actual Broadcaster implementation.  The
  /// Broadcaster makes a BroadcasterImpl which lives as long as it does.  The
  /// Listeners & the Events hold a weak pointer to the BroadcasterImpl, so
  /// that they can survive if a Broadcaster they were listening to is
  /// destroyed w/o their being able to unregister from it (which can happen if
  /// the Broadcasters & Listeners are being destroyed on separate threads
  /// simultaneously. The Broadcaster itself can't be shared out as a weak
  /// pointer, because some things that are broadcasters (e.g. the Target and
  /// the Process) are shared in their own right.
  ///
  /// For the most part, the Broadcaster functions dispatch to the
  /// BroadcasterImpl, and are documented in the public Broadcaster API above.
  class BroadcasterImpl {
    friend class Listener;
    friend class Broadcaster;

  public:
    BroadcasterImpl(Broadcaster &broadcaster);

    ~BroadcasterImpl() = default;

    void BroadcastEvent(lldb::EventSP &event_sp);

    void BroadcastEventIfUnique(lldb::EventSP &event_sp);

    void BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr);

    void BroadcastEvent(uint32_t event_type,
                        const lldb::EventDataSP &event_data_sp);

    void BroadcastEventIfUnique(uint32_t event_type,
                                EventData *event_data = nullptr);

    void Clear();

    uint32_t AddListener(const lldb::ListenerSP &listener_sp,
                         uint32_t event_mask);

    const char *GetBroadcasterName() const {
      return m_broadcaster.GetBroadcasterName().AsCString();
    }

    Broadcaster *GetBroadcaster();

    bool GetEventNames(Stream &s, const uint32_t event_mask,
                       bool prefix_with_broadcaster_name) const;

    void SetEventName(uint32_t event_mask, const char *name) {
      m_event_names[event_mask] = name;
    }

    const char *GetEventName(uint32_t event_mask) const {
      const auto pos = m_event_names.find(event_mask);
      if (pos != m_event_names.end())
        return pos->second.c_str();
      return nullptr;
    }

    bool EventTypeHasListeners(uint32_t event_type);

    bool RemoveListener(lldb_private::Listener *listener,
                        uint32_t event_mask = UINT32_MAX);

    bool RemoveListener(const lldb::ListenerSP &listener_sp,
                        uint32_t event_mask = UINT32_MAX);

    bool HijackBroadcaster(const lldb::ListenerSP &listener_sp,
                           uint32_t event_mask = UINT32_MAX);

    bool IsHijackedForEvent(uint32_t event_mask);

    void RestoreBroadcaster();

  protected:
    void PrivateBroadcastEvent(lldb::EventSP &event_sp, bool unique);

    const char *GetHijackingListenerName();

    typedef llvm::SmallVector<std::pair<lldb::ListenerWP, uint32_t>, 4>
        collection;
    typedef std::map<uint32_t, std::string> event_names_map;

    llvm::SmallVector<std::pair<lldb::ListenerSP, uint32_t &>, 4>
    GetListeners();

    /// The broadcaster that this implements.
    Broadcaster &m_broadcaster;

    /// Optionally define event names for readability and logging for each
    /// event bit.
    event_names_map m_event_names;

    /// A list of Listener / event_mask pairs that are listening to this
    /// broadcaster.
    collection m_listeners;

    /// A mutex that protects \a m_listeners.
    std::recursive_mutex m_listeners_mutex;

    /// A simple mechanism to intercept events from a broadcaster
    std::vector<lldb::ListenerSP> m_hijacking_listeners;

    /// At some point we may want to have a stack or Listener collections, but
    /// for now this is just for private hijacking.
    std::vector<uint32_t> m_hijacking_masks;

  private:
    BroadcasterImpl(const BroadcasterImpl &) = delete;
    const BroadcasterImpl &operator=(const BroadcasterImpl &) = delete;
  };

  typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP;
  typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP;

  BroadcasterImplSP GetBroadcasterImpl() { return m_broadcaster_sp; }

  const char *GetHijackingListenerName() {
    return m_broadcaster_sp->GetHijackingListenerName();
  }

private:
  BroadcasterImplSP m_broadcaster_sp;
  lldb::BroadcasterManagerSP m_manager_sp;

  /// The name of this broadcaster object.
  const ConstString m_broadcaster_name;

  Broadcaster(const Broadcaster &) = delete;
  const Broadcaster &operator=(const Broadcaster &) = delete;
};

} // namespace lldb_private

#endif // LLDB_UTILITY_BROADCASTER_H
