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