//===-- SBListener.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/SBListener.h"
#include "SBReproducerPrivate.h"
#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Utility/Broadcaster.h"
#include "lldb/Utility/Listener.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb;
using namespace lldb_private;

SBListener::SBListener() : m_opaque_sp() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBListener);
}

SBListener::SBListener(const char *name)
    : m_opaque_sp(Listener::MakeListener(name)), m_unused_ptr(nullptr) {
  LLDB_RECORD_CONSTRUCTOR(SBListener, (const char *), name);
}

SBListener::SBListener(const SBListener &rhs)
    : m_opaque_sp(rhs.m_opaque_sp), m_unused_ptr(nullptr) {
  LLDB_RECORD_CONSTRUCTOR(SBListener, (const lldb::SBListener &), rhs);
}

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

  if (this != &rhs) {
    m_opaque_sp = rhs.m_opaque_sp;
    m_unused_ptr = nullptr;
  }
  return LLDB_RECORD_RESULT(*this);
}

SBListener::SBListener(const lldb::ListenerSP &listener_sp)
    : m_opaque_sp(listener_sp), m_unused_ptr(nullptr) {}

SBListener::~SBListener() = default;

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

  return m_opaque_sp != nullptr;
}

void SBListener::AddEvent(const SBEvent &event) {
  LLDB_RECORD_METHOD(void, SBListener, AddEvent, (const lldb::SBEvent &),
                     event);

  EventSP &event_sp = event.GetSP();
  if (event_sp)
    m_opaque_sp->AddEvent(event_sp);
}

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

  if (m_opaque_sp)
    m_opaque_sp->Clear();
}

uint32_t SBListener::StartListeningForEventClass(SBDebugger &debugger,
                                                 const char *broadcaster_class,
                                                 uint32_t event_mask) {
  LLDB_RECORD_METHOD(uint32_t, SBListener, StartListeningForEventClass,
                     (lldb::SBDebugger &, const char *, uint32_t), debugger,
                     broadcaster_class, event_mask);

  if (m_opaque_sp) {
    Debugger *lldb_debugger = debugger.get();
    if (!lldb_debugger)
      return 0;
    BroadcastEventSpec event_spec(ConstString(broadcaster_class), event_mask);
    return m_opaque_sp->StartListeningForEventSpec(
        lldb_debugger->GetBroadcasterManager(), event_spec);
  } else
    return 0;
}

bool SBListener::StopListeningForEventClass(SBDebugger &debugger,
                                            const char *broadcaster_class,
                                            uint32_t event_mask) {
  LLDB_RECORD_METHOD(bool, SBListener, StopListeningForEventClass,
                     (lldb::SBDebugger &, const char *, uint32_t), debugger,
                     broadcaster_class, event_mask);

  if (m_opaque_sp) {
    Debugger *lldb_debugger = debugger.get();
    if (!lldb_debugger)
      return false;
    BroadcastEventSpec event_spec(ConstString(broadcaster_class), event_mask);
    return m_opaque_sp->StopListeningForEventSpec(
        lldb_debugger->GetBroadcasterManager(), event_spec);
  } else
    return false;
}

uint32_t SBListener::StartListeningForEvents(const SBBroadcaster &broadcaster,
                                             uint32_t event_mask) {
  LLDB_RECORD_METHOD(uint32_t, SBListener, StartListeningForEvents,
                     (const lldb::SBBroadcaster &, uint32_t), broadcaster,
                     event_mask);

  uint32_t acquired_event_mask = 0;
  if (m_opaque_sp && broadcaster.IsValid()) {
    acquired_event_mask =
        m_opaque_sp->StartListeningForEvents(broadcaster.get(), event_mask);
  }

  return acquired_event_mask;
}

bool SBListener::StopListeningForEvents(const SBBroadcaster &broadcaster,
                                        uint32_t event_mask) {
  LLDB_RECORD_METHOD(bool, SBListener, StopListeningForEvents,
                     (const lldb::SBBroadcaster &, uint32_t), broadcaster,
                     event_mask);

  if (m_opaque_sp && broadcaster.IsValid()) {
    return m_opaque_sp->StopListeningForEvents(broadcaster.get(), event_mask);
  }
  return false;
}

bool SBListener::WaitForEvent(uint32_t timeout_secs, SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, WaitForEvent,
                     (uint32_t, lldb::SBEvent &), timeout_secs, event);

  bool success = false;

  if (m_opaque_sp) {
    Timeout<std::micro> timeout(llvm::None);
    if (timeout_secs != UINT32_MAX) {
      assert(timeout_secs != 0); // Take this out after all calls with timeout
                                 // set to zero have been removed....
      timeout = std::chrono::seconds(timeout_secs);
    }
    EventSP event_sp;
    if (m_opaque_sp->GetEvent(event_sp, timeout)) {
      event.reset(event_sp);
      success = true;
    }
  }

  if (!success)
    event.reset(nullptr);
  return success;
}

bool SBListener::WaitForEventForBroadcaster(uint32_t num_seconds,
                                            const SBBroadcaster &broadcaster,
                                            SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, WaitForEventForBroadcaster,
                     (uint32_t, const lldb::SBBroadcaster &, lldb::SBEvent &),
                     num_seconds, broadcaster, event);

  if (m_opaque_sp && broadcaster.IsValid()) {
    Timeout<std::micro> timeout(llvm::None);
    if (num_seconds != UINT32_MAX)
      timeout = std::chrono::seconds(num_seconds);
    EventSP event_sp;
    if (m_opaque_sp->GetEventForBroadcaster(broadcaster.get(), event_sp,
                                            timeout)) {
      event.reset(event_sp);
      return true;
    }
  }
  event.reset(nullptr);
  return false;
}

bool SBListener::WaitForEventForBroadcasterWithType(
    uint32_t num_seconds, const SBBroadcaster &broadcaster,
    uint32_t event_type_mask, SBEvent &event) {
  LLDB_RECORD_METHOD(
      bool, SBListener, WaitForEventForBroadcasterWithType,
      (uint32_t, const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
      num_seconds, broadcaster, event_type_mask, event);

  if (m_opaque_sp && broadcaster.IsValid()) {
    Timeout<std::micro> timeout(llvm::None);
    if (num_seconds != UINT32_MAX)
      timeout = std::chrono::seconds(num_seconds);
    EventSP event_sp;
    if (m_opaque_sp->GetEventForBroadcasterWithType(
            broadcaster.get(), event_type_mask, event_sp, timeout)) {
      event.reset(event_sp);
      return true;
    }
  }
  event.reset(nullptr);
  return false;
}

bool SBListener::PeekAtNextEvent(SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEvent, (lldb::SBEvent &),
                     event);

  if (m_opaque_sp) {
    event.reset(m_opaque_sp->PeekAtNextEvent());
    return event.IsValid();
  }
  event.reset(nullptr);
  return false;
}

bool SBListener::PeekAtNextEventForBroadcaster(const SBBroadcaster &broadcaster,
                                               SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEventForBroadcaster,
                     (const lldb::SBBroadcaster &, lldb::SBEvent &),
                     broadcaster, event);

  if (m_opaque_sp && broadcaster.IsValid()) {
    event.reset(m_opaque_sp->PeekAtNextEventForBroadcaster(broadcaster.get()));
    return event.IsValid();
  }
  event.reset(nullptr);
  return false;
}

bool SBListener::PeekAtNextEventForBroadcasterWithType(
    const SBBroadcaster &broadcaster, uint32_t event_type_mask,
    SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, PeekAtNextEventForBroadcasterWithType,
                     (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
                     broadcaster, event_type_mask, event);

  if (m_opaque_sp && broadcaster.IsValid()) {
    event.reset(m_opaque_sp->PeekAtNextEventForBroadcasterWithType(
        broadcaster.get(), event_type_mask));
    return event.IsValid();
  }
  event.reset(nullptr);
  return false;
}

bool SBListener::GetNextEvent(SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, GetNextEvent, (lldb::SBEvent &), event);

  if (m_opaque_sp) {
    EventSP event_sp;
    if (m_opaque_sp->GetEvent(event_sp, std::chrono::seconds(0))) {
      event.reset(event_sp);
      return true;
    }
  }
  event.reset(nullptr);
  return false;
}

bool SBListener::GetNextEventForBroadcaster(const SBBroadcaster &broadcaster,
                                            SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, GetNextEventForBroadcaster,
                     (const lldb::SBBroadcaster &, lldb::SBEvent &),
                     broadcaster, event);

  if (m_opaque_sp && broadcaster.IsValid()) {
    EventSP event_sp;
    if (m_opaque_sp->GetEventForBroadcaster(broadcaster.get(), event_sp,
                                            std::chrono::seconds(0))) {
      event.reset(event_sp);
      return true;
    }
  }
  event.reset(nullptr);
  return false;
}

bool SBListener::GetNextEventForBroadcasterWithType(
    const SBBroadcaster &broadcaster, uint32_t event_type_mask,
    SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, GetNextEventForBroadcasterWithType,
                     (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &),
                     broadcaster, event_type_mask, event);

  if (m_opaque_sp && broadcaster.IsValid()) {
    EventSP event_sp;
    if (m_opaque_sp->GetEventForBroadcasterWithType(broadcaster.get(),
                                                    event_type_mask, event_sp,
                                                    std::chrono::seconds(0))) {
      event.reset(event_sp);
      return true;
    }
  }
  event.reset(nullptr);
  return false;
}

bool SBListener::HandleBroadcastEvent(const SBEvent &event) {
  LLDB_RECORD_METHOD(bool, SBListener, HandleBroadcastEvent,
                     (const lldb::SBEvent &), event);

  if (m_opaque_sp)
    return m_opaque_sp->HandleBroadcastEvent(event.GetSP());
  return false;
}

lldb::ListenerSP SBListener::GetSP() { return m_opaque_sp; }

Listener *SBListener::operator->() const { return m_opaque_sp.get(); }

Listener *SBListener::get() const { return m_opaque_sp.get(); }

void SBListener::reset(ListenerSP listener_sp) {
  m_opaque_sp = listener_sp;
  m_unused_ptr = nullptr;
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBListener>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBListener, ());
  LLDB_REGISTER_CONSTRUCTOR(SBListener, (const char *));
  LLDB_REGISTER_CONSTRUCTOR(SBListener, (const lldb::SBListener &));
  LLDB_REGISTER_METHOD(const lldb::SBListener &,
                       SBListener, operator=,(const lldb::SBListener &));
  LLDB_REGISTER_METHOD_CONST(bool, SBListener, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBListener, operator bool, ());
  LLDB_REGISTER_METHOD(void, SBListener, AddEvent, (const lldb::SBEvent &));
  LLDB_REGISTER_METHOD(void, SBListener, Clear, ());
  LLDB_REGISTER_METHOD(uint32_t, SBListener, StartListeningForEventClass,
                       (lldb::SBDebugger &, const char *, uint32_t));
  LLDB_REGISTER_METHOD(bool, SBListener, StopListeningForEventClass,
                       (lldb::SBDebugger &, const char *, uint32_t));
  LLDB_REGISTER_METHOD(uint32_t, SBListener, StartListeningForEvents,
                       (const lldb::SBBroadcaster &, uint32_t));
  LLDB_REGISTER_METHOD(bool, SBListener, StopListeningForEvents,
                       (const lldb::SBBroadcaster &, uint32_t));
  LLDB_REGISTER_METHOD(bool, SBListener, WaitForEvent,
                       (uint32_t, lldb::SBEvent &));
  LLDB_REGISTER_METHOD(
      bool, SBListener, WaitForEventForBroadcaster,
      (uint32_t, const lldb::SBBroadcaster &, lldb::SBEvent &));
  LLDB_REGISTER_METHOD(
      bool, SBListener, WaitForEventForBroadcasterWithType,
      (uint32_t, const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
  LLDB_REGISTER_METHOD(bool, SBListener, PeekAtNextEvent, (lldb::SBEvent &));
  LLDB_REGISTER_METHOD(bool, SBListener, PeekAtNextEventForBroadcaster,
                       (const lldb::SBBroadcaster &, lldb::SBEvent &));
  LLDB_REGISTER_METHOD(
      bool, SBListener, PeekAtNextEventForBroadcasterWithType,
      (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
  LLDB_REGISTER_METHOD(bool, SBListener, GetNextEvent, (lldb::SBEvent &));
  LLDB_REGISTER_METHOD(bool, SBListener, GetNextEventForBroadcaster,
                       (const lldb::SBBroadcaster &, lldb::SBEvent &));
  LLDB_REGISTER_METHOD(
      bool, SBListener, GetNextEventForBroadcasterWithType,
      (const lldb::SBBroadcaster &, uint32_t, lldb::SBEvent &));
  LLDB_REGISTER_METHOD(bool, SBListener, HandleBroadcastEvent,
                       (const lldb::SBEvent &));
}

}
}
