//===-- SBEvent.cpp -------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBEvent.h"
#include "SBReproducerPrivate.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBStream.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Target/Process.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/Stream.h"

using namespace lldb;
using namespace lldb_private;

SBEvent::SBEvent() : m_event_sp(), m_opaque_ptr(nullptr) {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBEvent);
}

SBEvent::SBEvent(uint32_t event_type, const char *cstr, uint32_t cstr_len)
    : m_event_sp(new Event(event_type, new EventDataBytes(cstr, cstr_len))),
      m_opaque_ptr(m_event_sp.get()) {
  LLDB_RECORD_CONSTRUCTOR(SBEvent, (uint32_t, const char *, uint32_t),
                          event_type, cstr, cstr_len);
}

SBEvent::SBEvent(EventSP &event_sp)
    : m_event_sp(event_sp), m_opaque_ptr(event_sp.get()) {
  LLDB_RECORD_CONSTRUCTOR(SBEvent, (lldb::EventSP &), event_sp);
}

SBEvent::SBEvent(Event *event_ptr) : m_event_sp(), m_opaque_ptr(event_ptr) {
  LLDB_RECORD_CONSTRUCTOR(SBEvent, (lldb_private::Event *), event_ptr);
}

SBEvent::SBEvent(const SBEvent &rhs)
    : m_event_sp(rhs.m_event_sp), m_opaque_ptr(rhs.m_opaque_ptr) {
  LLDB_RECORD_CONSTRUCTOR(SBEvent, (const lldb::SBEvent &), rhs);
}

const SBEvent &SBEvent::operator=(const SBEvent &rhs) {
  LLDB_RECORD_METHOD(const lldb::SBEvent &,
                     SBEvent, operator=,(const lldb::SBEvent &), rhs);

  if (this != &rhs) {
    m_event_sp = rhs.m_event_sp;
    m_opaque_ptr = rhs.m_opaque_ptr;
  }
  return LLDB_RECORD_RESULT(*this);
}

SBEvent::~SBEvent() = default;

const char *SBEvent::GetDataFlavor() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBEvent, GetDataFlavor);

  Event *lldb_event = get();
  if (lldb_event) {
    EventData *event_data = lldb_event->GetData();
    if (event_data)
      return lldb_event->GetData()->GetFlavor().AsCString();
  }
  return nullptr;
}

uint32_t SBEvent::GetType() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBEvent, GetType);


  const Event *lldb_event = get();
  uint32_t event_type = 0;
  if (lldb_event)
    event_type = lldb_event->GetType();


  return event_type;
}

SBBroadcaster SBEvent::GetBroadcaster() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBBroadcaster, SBEvent,
                                   GetBroadcaster);

  SBBroadcaster broadcaster;
  const Event *lldb_event = get();
  if (lldb_event)
    broadcaster.reset(lldb_event->GetBroadcaster(), false);
  return LLDB_RECORD_RESULT(broadcaster);
}

const char *SBEvent::GetBroadcasterClass() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBEvent, GetBroadcasterClass);

  const Event *lldb_event = get();
  if (lldb_event)
    return lldb_event->GetBroadcaster()->GetBroadcasterClass().AsCString();
  else
    return "unknown class";
}

bool SBEvent::BroadcasterMatchesPtr(const SBBroadcaster *broadcaster) {
  LLDB_RECORD_METHOD(bool, SBEvent, BroadcasterMatchesPtr,
                     (const lldb::SBBroadcaster *), broadcaster);

  if (broadcaster)
    return BroadcasterMatchesRef(*broadcaster);
  return false;
}

bool SBEvent::BroadcasterMatchesRef(const SBBroadcaster &broadcaster) {
  LLDB_RECORD_METHOD(bool, SBEvent, BroadcasterMatchesRef,
                     (const lldb::SBBroadcaster &), broadcaster);

  Event *lldb_event = get();
  bool success = false;
  if (lldb_event)
    success = lldb_event->BroadcasterIs(broadcaster.get());


  return success;
}

void SBEvent::Clear() {
  LLDB_RECORD_METHOD_NO_ARGS(void, SBEvent, Clear);

  Event *lldb_event = get();
  if (lldb_event)
    lldb_event->Clear();
}

EventSP &SBEvent::GetSP() const { return m_event_sp; }

Event *SBEvent::get() const {
  // There is a dangerous accessor call GetSharedPtr which can be used, so if
  // we have anything valid in m_event_sp, we must use that since if it gets
  // used by a function that puts something in there, then it won't update
  // m_opaque_ptr...
  if (m_event_sp)
    m_opaque_ptr = m_event_sp.get();

  return m_opaque_ptr;
}

void SBEvent::reset(EventSP &event_sp) {
  m_event_sp = event_sp;
  m_opaque_ptr = m_event_sp.get();
}

void SBEvent::reset(Event *event_ptr) {
  m_opaque_ptr = event_ptr;
  m_event_sp.reset();
}

bool SBEvent::IsValid() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBEvent, IsValid);
  return this->operator bool();
}
SBEvent::operator bool() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBEvent, operator bool);

  // Do NOT use m_opaque_ptr directly!!! Must use the SBEvent::get() accessor.
  // See comments in SBEvent::get()....
  return SBEvent::get() != nullptr;
}

const char *SBEvent::GetCStringFromEvent(const SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(const char *, SBEvent, GetCStringFromEvent,
                            (const lldb::SBEvent &), event);

  return static_cast<const char *>(
      EventDataBytes::GetBytesFromEvent(event.get()));
}

bool SBEvent::GetDescription(SBStream &description) {
  LLDB_RECORD_METHOD(bool, SBEvent, GetDescription, (lldb::SBStream &),
                     description);

  Stream &strm = description.ref();

  if (get()) {
    m_opaque_ptr->Dump(&strm);
  } else
    strm.PutCString("No value");

  return true;
}

bool SBEvent::GetDescription(SBStream &description) const {
  LLDB_RECORD_METHOD_CONST(bool, SBEvent, GetDescription, (lldb::SBStream &),
                           description);

  Stream &strm = description.ref();

  if (get()) {
    m_opaque_ptr->Dump(&strm);
  } else
    strm.PutCString("No value");

  return true;
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBEvent>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBEvent, ());
  LLDB_REGISTER_CONSTRUCTOR(SBEvent, (uint32_t, const char *, uint32_t));
  LLDB_REGISTER_CONSTRUCTOR(SBEvent, (lldb::EventSP &));
  LLDB_REGISTER_CONSTRUCTOR(SBEvent, (lldb_private::Event *));
  LLDB_REGISTER_CONSTRUCTOR(SBEvent, (const lldb::SBEvent &));
  LLDB_REGISTER_METHOD(const lldb::SBEvent &,
                       SBEvent, operator=,(const lldb::SBEvent &));
  LLDB_REGISTER_METHOD(const char *, SBEvent, GetDataFlavor, ());
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBEvent, GetType, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBBroadcaster, SBEvent, GetBroadcaster,
                             ());
  LLDB_REGISTER_METHOD_CONST(const char *, SBEvent, GetBroadcasterClass, ());
  LLDB_REGISTER_METHOD(bool, SBEvent, BroadcasterMatchesPtr,
                       (const lldb::SBBroadcaster *));
  LLDB_REGISTER_METHOD(bool, SBEvent, BroadcasterMatchesRef,
                       (const lldb::SBBroadcaster &));
  LLDB_REGISTER_METHOD(void, SBEvent, Clear, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBEvent, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBEvent, operator bool, ());
  LLDB_REGISTER_STATIC_METHOD(const char *, SBEvent, GetCStringFromEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_METHOD(bool, SBEvent, GetDescription, (lldb::SBStream &));
  LLDB_REGISTER_METHOD_CONST(bool, SBEvent, GetDescription,
                             (lldb::SBStream &));
}

}
}
