//===-- SBBroadcaster.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/Utility/Broadcaster.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Instrumentation.h"

#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBListener.h"
#include "lldb/Utility/StringPool.h"

using namespace lldb;
using namespace lldb_private;

SBBroadcaster::SBBroadcaster() { LLDB_INSTRUMENT_VA(this); }

SBBroadcaster::SBBroadcaster(const char *name)
    : m_opaque_sp(new Broadcaster(nullptr, name)) {
  LLDB_INSTRUMENT_VA(this, name);

  m_opaque_ptr = m_opaque_sp.get();
}

SBBroadcaster::SBBroadcaster(lldb_private::Broadcaster *broadcaster, bool owns)
    : m_opaque_sp(owns ? broadcaster : nullptr), m_opaque_ptr(broadcaster) {}

SBBroadcaster::SBBroadcaster(const SBBroadcaster &rhs)
    : m_opaque_sp(rhs.m_opaque_sp), m_opaque_ptr(rhs.m_opaque_ptr) {
  LLDB_INSTRUMENT_VA(this, rhs);
}

const SBBroadcaster &SBBroadcaster::operator=(const SBBroadcaster &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

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

SBBroadcaster::~SBBroadcaster() { reset(nullptr, false); }

void SBBroadcaster::BroadcastEventByType(uint32_t event_type, bool unique) {
  LLDB_INSTRUMENT_VA(this, event_type, unique);

  if (m_opaque_ptr == nullptr)
    return;

  if (unique)
    m_opaque_ptr->BroadcastEventIfUnique(event_type);
  else
    m_opaque_ptr->BroadcastEvent(event_type);
}

void SBBroadcaster::BroadcastEvent(const SBEvent &event, bool unique) {
  LLDB_INSTRUMENT_VA(this, event, unique);

  if (m_opaque_ptr == nullptr)
    return;

  EventSP event_sp = event.GetSP();
  if (unique)
    m_opaque_ptr->BroadcastEventIfUnique(event_sp);
  else
    m_opaque_ptr->BroadcastEvent(event_sp);
}

void SBBroadcaster::AddInitialEventsToListener(const SBListener &listener,
                                               uint32_t requested_events) {
  LLDB_INSTRUMENT_VA(this, listener, requested_events);

  if (m_opaque_ptr)
    m_opaque_ptr->AddInitialEventsToListener(listener.m_opaque_sp,
                                             requested_events);
}

uint32_t SBBroadcaster::AddListener(const SBListener &listener,
                                    uint32_t event_mask) {
  LLDB_INSTRUMENT_VA(this, listener, event_mask);

  if (m_opaque_ptr)
    return m_opaque_ptr->AddListener(listener.m_opaque_sp, event_mask);
  return 0;
}

const char *SBBroadcaster::GetName() const {
  LLDB_INSTRUMENT_VA(this);

  if (m_opaque_ptr)
    return StringPool::GetSystemPool().Intern(
        m_opaque_ptr->GetBroadcasterName());
  return nullptr;
}

bool SBBroadcaster::EventTypeHasListeners(uint32_t event_type) {
  LLDB_INSTRUMENT_VA(this, event_type);

  if (m_opaque_ptr)
    return m_opaque_ptr->EventTypeHasListeners(event_type);
  return false;
}

bool SBBroadcaster::RemoveListener(const SBListener &listener,
                                   uint32_t event_mask) {
  LLDB_INSTRUMENT_VA(this, listener, event_mask);

  if (m_opaque_ptr)
    return m_opaque_ptr->RemoveListener(listener.m_opaque_sp, event_mask);
  return false;
}

Broadcaster *SBBroadcaster::get() const { return m_opaque_ptr; }

void SBBroadcaster::reset(Broadcaster *broadcaster, bool owns) {
  if (owns)
    m_opaque_sp.reset(broadcaster);
  else
    m_opaque_sp.reset();
  m_opaque_ptr = broadcaster;
}

bool SBBroadcaster::IsValid() const {
  LLDB_INSTRUMENT_VA(this);
  return this->operator bool();
}
SBBroadcaster::operator bool() const {
  LLDB_INSTRUMENT_VA(this);

  return m_opaque_ptr != nullptr;
}

void SBBroadcaster::Clear() {
  LLDB_INSTRUMENT_VA(this);

  m_opaque_sp.reset();
  m_opaque_ptr = nullptr;
}

bool SBBroadcaster::operator==(const SBBroadcaster &rhs) const {
  LLDB_INSTRUMENT_VA(this, rhs);

  return m_opaque_ptr == rhs.m_opaque_ptr;
}

bool SBBroadcaster::operator!=(const SBBroadcaster &rhs) const {
  LLDB_INSTRUMENT_VA(this, rhs);

  return m_opaque_ptr != rhs.m_opaque_ptr;
}

bool SBBroadcaster::operator<(const SBBroadcaster &rhs) const {
  LLDB_INSTRUMENT_VA(this, rhs);

  return m_opaque_ptr < rhs.m_opaque_ptr;
}
