//===-- Event.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_EVENT_H
#define LLDB_UTILITY_EVENT_H

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

#include "llvm/ADT/StringRef.h"

#include <chrono>
#include <memory>
#include <string>

#include <cstddef>
#include <cstdint>

namespace lldb_private {
class Event;
class Stream;
}

namespace lldb_private {

// lldb::EventData
class EventData {
  friend class Event;

public:
  EventData();

  virtual ~EventData();

  virtual ConstString GetFlavor() const = 0;
  
  virtual Log *GetLogChannel() { return nullptr; }
  
  virtual void Dump(Stream *s) const;

private:
  virtual void DoOnRemoval(Event *event_ptr) {}

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

// lldb::EventDataBytes
class EventDataBytes : public EventData {
public:
  // Constructors
  EventDataBytes();

  EventDataBytes(const char *cstr);

  EventDataBytes(llvm::StringRef str);

  EventDataBytes(const void *src, size_t src_len);

  ~EventDataBytes() override;

  // Member functions
  ConstString GetFlavor() const override;

  void Dump(Stream *s) const override;

  const void *GetBytes() const;

  size_t GetByteSize() const;

  void SetBytes(const void *src, size_t src_len);

  void SwapBytes(std::string &new_bytes);

  void SetBytesFromCString(const char *cstr);

  // Static functions
  static const EventDataBytes *GetEventDataFromEvent(const Event *event_ptr);

  static const void *GetBytesFromEvent(const Event *event_ptr);

  static size_t GetByteSizeFromEvent(const Event *event_ptr);

  static ConstString GetFlavorString();

private:
  std::string m_bytes;

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

class EventDataReceipt : public EventData {
public:
  EventDataReceipt() : m_predicate(false) {}

  ~EventDataReceipt() override = default;

  static ConstString GetFlavorString() {
    static ConstString g_flavor("Process::ProcessEventData");
    return g_flavor;
  }

  ConstString GetFlavor() const override { return GetFlavorString(); }

  bool WaitForEventReceived(const Timeout<std::micro> &timeout = llvm::None) {
    return m_predicate.WaitForValueEqualTo(true, timeout);
  }

private:
  Predicate<bool> m_predicate;

  void DoOnRemoval(Event *event_ptr) override {
    m_predicate.SetValue(true, eBroadcastAlways);
  }
};

/// This class handles one or more StructuredData::Dictionary entries
/// that are raised for structured data events.

class EventDataStructuredData : public EventData {
public:
  // Constructors
  EventDataStructuredData();

  EventDataStructuredData(const lldb::ProcessSP &process_sp,
                          const StructuredData::ObjectSP &object_sp,
                          const lldb::StructuredDataPluginSP &plugin_sp);

  ~EventDataStructuredData() override;

  // Member functions
  ConstString GetFlavor() const override;

  void Dump(Stream *s) const override;

  const lldb::ProcessSP &GetProcess() const;

  const StructuredData::ObjectSP &GetObject() const;

  const lldb::StructuredDataPluginSP &GetStructuredDataPlugin() const;

  void SetProcess(const lldb::ProcessSP &process_sp);

  void SetObject(const StructuredData::ObjectSP &object_sp);

  void SetStructuredDataPlugin(const lldb::StructuredDataPluginSP &plugin_sp);

  // Static functions
  static const EventDataStructuredData *
  GetEventDataFromEvent(const Event *event_ptr);

  static lldb::ProcessSP GetProcessFromEvent(const Event *event_ptr);

  static StructuredData::ObjectSP GetObjectFromEvent(const Event *event_ptr);

  static lldb::StructuredDataPluginSP
  GetPluginFromEvent(const Event *event_ptr);

  static ConstString GetFlavorString();

private:
  lldb::ProcessSP m_process_sp;
  StructuredData::ObjectSP m_object_sp;
  lldb::StructuredDataPluginSP m_plugin_sp;

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

// lldb::Event
class Event {
  friend class Listener;
  friend class EventData;
  friend class Broadcaster::BroadcasterImpl;

public:
  Event(Broadcaster *broadcaster, uint32_t event_type,
        EventData *data = nullptr);

  Event(Broadcaster *broadcaster, uint32_t event_type,
        const lldb::EventDataSP &event_data_sp);

  Event(uint32_t event_type, EventData *data = nullptr);

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

  ~Event();

  void Dump(Stream *s) const;

  EventData *GetData() { return m_data_sp.get(); }

  const EventData *GetData() const { return m_data_sp.get(); }

  void SetData(EventData *new_data) { m_data_sp.reset(new_data); }

  uint32_t GetType() const { return m_type; }

  void SetType(uint32_t new_type) { m_type = new_type; }

  Broadcaster *GetBroadcaster() const {
    Broadcaster::BroadcasterImplSP broadcaster_impl_sp =
        m_broadcaster_wp.lock();
    if (broadcaster_impl_sp)
      return broadcaster_impl_sp->GetBroadcaster();
    else
      return nullptr;
  }

  bool BroadcasterIs(Broadcaster *broadcaster) {
    Broadcaster::BroadcasterImplSP broadcaster_impl_sp =
        m_broadcaster_wp.lock();
    if (broadcaster_impl_sp)
      return broadcaster_impl_sp->GetBroadcaster() == broadcaster;
    else
      return false;
  }

  void Clear() { m_data_sp.reset(); }

private:
  // This is only called by Listener when it pops an event off the queue for
  // the listener.  It calls the Event Data's DoOnRemoval() method, which is
  // virtual and can be overridden by the specific data classes.

  void DoOnRemoval();

  // Called by Broadcaster::BroadcastEvent prior to letting all the listeners
  // know about it update the contained broadcaster so that events can be
  // popped off one queue and re-broadcast to others.
  void SetBroadcaster(Broadcaster *broadcaster) {
    m_broadcaster_wp = broadcaster->GetBroadcasterImpl();
  }

  Broadcaster::BroadcasterImplWP
      m_broadcaster_wp;        // The broadcaster that sent this event
  uint32_t m_type;             // The bit describing this event
  lldb::EventDataSP m_data_sp; // User specific data for this event

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

} // namespace lldb_private

#endif // LLDB_UTILITY_EVENT_H
