//===-- 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;
  BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs);

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.
  ///
  /// \param[in] event_type
  ///     The element from the enum defining this broadcaster's events
  ///     that is being broadcast.
  ///
  /// \param[in] event_data
  ///     User event data that will be owned by the lldb::Event that
  ///     is created internally.
  ///
  /// \param[in] unique
  ///     If true, then only add an event of this type if there isn't
  ///     one already in the queue.
  ///
  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
  ///     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.
  ///
  /// \return
  ///     The NULL terminated C string name of this Broadcaster.
  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
  ///     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
  ///     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:
    DISALLOW_COPY_AND_ASSIGN(BroadcasterImpl);
  };

  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;

  DISALLOW_COPY_AND_ASSIGN(Broadcaster);
};

} // namespace lldb_private

#endif // LLDB_UTILITY_BROADCASTER_H
