//===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBBreakpointLocation.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBThread.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadSpec.h"

#include "lldb/lldb-enumerations.h"

#include "llvm/ADT/STLExtras.h"

using namespace lldb;
using namespace lldb_private;

struct CallbackData {
  SBBreakpoint::BreakpointHitCallback callback;
  void *callback_baton;
};

class SBBreakpointCallbackBaton : public TypedBaton<CallbackData> {
public:
  SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
                            void *baton)
      : TypedBaton(llvm::make_unique<CallbackData>()) {
    getItem()->callback = callback;
    getItem()->callback_baton = baton;
  }
};

SBBreakpoint::SBBreakpoint() : m_opaque_sp() {}

SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
    : m_opaque_sp(rhs.m_opaque_sp) {}

SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
    : m_opaque_sp(bp_sp) {}

SBBreakpoint::~SBBreakpoint() = default;

const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
  if (this != &rhs)
    m_opaque_sp = rhs.m_opaque_sp;
  return *this;
}

bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
  if (m_opaque_sp && rhs.m_opaque_sp)
    return m_opaque_sp.get() == rhs.m_opaque_sp.get();
  return false;
}

bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
  if (m_opaque_sp && rhs.m_opaque_sp)
    return m_opaque_sp.get() != rhs.m_opaque_sp.get();
  return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
}

break_id_t SBBreakpoint::GetID() const {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  break_id_t break_id = LLDB_INVALID_BREAK_ID;
  if (m_opaque_sp)
    break_id = m_opaque_sp->GetID();

  if (log) {
    if (break_id == LLDB_INVALID_BREAK_ID)
      log->Printf("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
                  static_cast<void *>(m_opaque_sp.get()));
    else
      log->Printf("SBBreakpoint(%p)::GetID () => %u",
                  static_cast<void *>(m_opaque_sp.get()), break_id);
  }

  return break_id;
}

bool SBBreakpoint::IsValid() const {
  if (!m_opaque_sp)
    return false;
  else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
    return true;
  else
    return false;
}

void SBBreakpoint::ClearAllBreakpointSites() {
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->ClearAllBreakpointSites();
  }
}

SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
  SBBreakpointLocation sb_bp_location;

  if (m_opaque_sp) {
    if (vm_addr != LLDB_INVALID_ADDRESS) {
      std::lock_guard<std::recursive_mutex> guard(
          m_opaque_sp->GetTarget().GetAPIMutex());
      Address address;
      Target &target = m_opaque_sp->GetTarget();
      if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
        address.SetRawAddress(vm_addr);
      }
      sb_bp_location.SetLocation(m_opaque_sp->FindLocationByAddress(address));
    }
  }
  return sb_bp_location;
}

break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
  break_id_t break_id = LLDB_INVALID_BREAK_ID;

  if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    Address address;
    Target &target = m_opaque_sp->GetTarget();
    if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
      address.SetRawAddress(vm_addr);
    }
    break_id = m_opaque_sp->FindLocationIDByAddress(address);
  }

  return break_id;
}

SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
  SBBreakpointLocation sb_bp_location;

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    sb_bp_location.SetLocation(m_opaque_sp->FindLocationByID(bp_loc_id));
  }

  return sb_bp_location;
}

SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
  SBBreakpointLocation sb_bp_location;

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    sb_bp_location.SetLocation(m_opaque_sp->GetLocationAtIndex(index));
  }

  return sb_bp_location;
}

void SBBreakpoint::SetEnabled(bool enable) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
                static_cast<void *>(m_opaque_sp.get()), enable);

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->SetEnabled(enable);
  }
}

bool SBBreakpoint::IsEnabled() {
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    return m_opaque_sp->IsEnabled();
  } else
    return false;
}

void SBBreakpoint::SetOneShot(bool one_shot) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
                static_cast<void *>(m_opaque_sp.get()), one_shot);

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->SetOneShot(one_shot);
  }
}

bool SBBreakpoint::IsOneShot() const {
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    return m_opaque_sp->IsOneShot();
  } else
    return false;
}

bool SBBreakpoint::IsInternal() {
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    return m_opaque_sp->IsInternal();
  } else
    return false;
}

void SBBreakpoint::SetIgnoreCount(uint32_t count) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
                static_cast<void *>(m_opaque_sp.get()), count);

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->SetIgnoreCount(count);
  }
}

void SBBreakpoint::SetCondition(const char *condition) {
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->SetCondition(condition);
  }
}

const char *SBBreakpoint::GetCondition() {
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    return m_opaque_sp->GetConditionText();
  }
  return nullptr;
}

uint32_t SBBreakpoint::GetHitCount() const {
  uint32_t count = 0;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    count = m_opaque_sp->GetHitCount();
  }

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::GetHitCount () => %u",
                static_cast<void *>(m_opaque_sp.get()), count);

  return count;
}

uint32_t SBBreakpoint::GetIgnoreCount() const {
  uint32_t count = 0;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    count = m_opaque_sp->GetIgnoreCount();
  }

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::GetIgnoreCount () => %u",
                static_cast<void *>(m_opaque_sp.get()), count);

  return count;
}

void SBBreakpoint::SetThreadID(tid_t tid) {
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->SetThreadID(tid);
  }
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
                static_cast<void *>(m_opaque_sp.get()), tid);
}

tid_t SBBreakpoint::GetThreadID() {
  tid_t tid = LLDB_INVALID_THREAD_ID;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    tid = m_opaque_sp->GetThreadID();
  }

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
                static_cast<void *>(m_opaque_sp.get()), tid);
  return tid;
}

void SBBreakpoint::SetThreadIndex(uint32_t index) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::SetThreadIndex (%u)",
                static_cast<void *>(m_opaque_sp.get()), index);
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
  }
}

uint32_t SBBreakpoint::GetThreadIndex() const {
  uint32_t thread_idx = UINT32_MAX;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    const ThreadSpec *thread_spec =
        m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
    if (thread_spec != nullptr)
      thread_idx = thread_spec->GetIndex();
  }
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::GetThreadIndex () => %u",
                static_cast<void *>(m_opaque_sp.get()), thread_idx);

  return thread_idx;
}

void SBBreakpoint::SetThreadName(const char *thread_name) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::SetThreadName (%s)",
                static_cast<void *>(m_opaque_sp.get()), thread_name);

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->GetOptions()->GetThreadSpec()->SetName(thread_name);
  }
}

const char *SBBreakpoint::GetThreadName() const {
  const char *name = nullptr;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    const ThreadSpec *thread_spec =
        m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
    if (thread_spec != nullptr)
      name = thread_spec->GetName();
  }
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::GetThreadName () => %s",
                static_cast<void *>(m_opaque_sp.get()), name);

  return name;
}

void SBBreakpoint::SetQueueName(const char *queue_name) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::SetQueueName (%s)",
                static_cast<void *>(m_opaque_sp.get()), queue_name);
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
  }
}

const char *SBBreakpoint::GetQueueName() const {
  const char *name = nullptr;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    const ThreadSpec *thread_spec =
        m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
    if (thread_spec)
      name = thread_spec->GetQueueName();
  }
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::GetQueueName () => %s",
                static_cast<void *>(m_opaque_sp.get()), name);

  return name;
}

size_t SBBreakpoint::GetNumResolvedLocations() const {
  size_t num_resolved = 0;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    num_resolved = m_opaque_sp->GetNumResolvedLocations();
  }
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
                static_cast<void *>(m_opaque_sp.get()),
                static_cast<uint64_t>(num_resolved));
  return num_resolved;
}

size_t SBBreakpoint::GetNumLocations() const {
  size_t num_locs = 0;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    num_locs = m_opaque_sp->GetNumLocations();
  }
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
  if (log)
    log->Printf("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
                static_cast<void *>(m_opaque_sp.get()),
                static_cast<uint64_t>(num_locs));
  return num_locs;
}

void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
  if (!m_opaque_sp)
    return;
  if (commands.GetSize() == 0)
    return;

  std::lock_guard<std::recursive_mutex> guard(
      m_opaque_sp->GetTarget().GetAPIMutex());
  std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
      new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));

  m_opaque_sp->GetOptions()->SetCommandDataCallback(cmd_data_up);
}

bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
  if (!m_opaque_sp)
    return false;
  StringList command_list;
  bool has_commands =
      m_opaque_sp->GetOptions()->GetCommandLineCallbacks(command_list);
  if (has_commands)
    commands.AppendList(command_list);
  return has_commands;
}

bool SBBreakpoint::GetDescription(SBStream &s) {
  return GetDescription(s, true);
}

bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
    m_opaque_sp->GetResolverDescription(s.get());
    m_opaque_sp->GetFilterDescription(s.get());
    if (include_locations) {
      const size_t num_locations = m_opaque_sp->GetNumLocations();
      s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
    }
    return true;
  }
  s.Printf("No value");
  return false;
}

bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
                                                StoppointCallbackContext *ctx,
                                                lldb::user_id_t break_id,
                                                lldb::user_id_t break_loc_id) {
  ExecutionContext exe_ctx(ctx->exe_ctx_ref);
  BreakpointSP bp_sp(
      exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
  if (baton && bp_sp) {
    CallbackData *data = (CallbackData *)baton;
    lldb_private::Breakpoint *bp = bp_sp.get();
    if (bp && data->callback) {
      Process *process = exe_ctx.GetProcessPtr();
      if (process) {
        SBProcess sb_process(process->shared_from_this());
        SBThread sb_thread;
        SBBreakpointLocation sb_location;
        assert(bp_sp);
        sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
        Thread *thread = exe_ctx.GetThreadPtr();
        if (thread)
          sb_thread.SetThread(thread->shared_from_this());

        return data->callback(data->callback_baton, sb_process, sb_thread,
                              sb_location);
      }
    }
  }
  return true; // Return true if we should stop at this breakpoint
}

void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log) {
    void *pointer = &callback;
    log->Printf("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
                static_cast<void *>(m_opaque_sp.get()),
                *static_cast<void **>(&pointer), static_cast<void *>(baton));
  }

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
    m_opaque_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback,
                             baton_sp, false);
  }
}

void SBBreakpoint::SetScriptCallbackFunction(
    const char *callback_function_name) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
                static_cast<void *>(m_opaque_sp.get()), callback_function_name);

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
    m_opaque_sp->GetTarget()
        .GetDebugger()
        .GetCommandInterpreter()
        .GetScriptInterpreter()
        ->SetBreakpointCommandCallbackFunction(bp_options,
                                               callback_function_name);
  }
}

SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
                static_cast<void *>(m_opaque_sp.get()), callback_body_text);

  SBError sb_error;
  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
    Error error =
        m_opaque_sp->GetTarget()
            .GetDebugger()
            .GetCommandInterpreter()
            .GetScriptInterpreter()
            ->SetBreakpointCommandCallback(bp_options, callback_body_text);
    sb_error.SetError(error);
  } else
    sb_error.SetErrorString("invalid breakpoint");

  return sb_error;
}

bool SBBreakpoint::AddName(const char *new_name) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::AddName (name=%s)",
                static_cast<void *>(m_opaque_sp.get()), new_name);

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    Error error; // Think I'm just going to swallow the error here, it's
                 // probably more annoying to have to provide it.
    return m_opaque_sp->AddName(new_name, error);
  }

  return false;
}

void SBBreakpoint::RemoveName(const char *name_to_remove) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::RemoveName (name=%s)",
                static_cast<void *>(m_opaque_sp.get()), name_to_remove);

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    m_opaque_sp->RemoveName(name_to_remove);
  }
}

bool SBBreakpoint::MatchesName(const char *name) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::MatchesName (name=%s)",
                static_cast<void *>(m_opaque_sp.get()), name);

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    return m_opaque_sp->MatchesName(name);
  }

  return false;
}

void SBBreakpoint::GetNames(SBStringList &names) {
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));

  if (log)
    log->Printf("SBBreakpoint(%p)::GetNames ()",
                static_cast<void *>(m_opaque_sp.get()));

  if (m_opaque_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        m_opaque_sp->GetTarget().GetAPIMutex());
    std::vector<std::string> names_vec;
    m_opaque_sp->GetNames(names_vec);
    for (std::string name : names_vec) {
      names.AppendString(name.c_str());
    }
  }
}

lldb_private::Breakpoint *SBBreakpoint::operator->() const {
  return m_opaque_sp.get();
}

lldb_private::Breakpoint *SBBreakpoint::get() const {
  return m_opaque_sp.get();
}

lldb::BreakpointSP &SBBreakpoint::operator*() { return m_opaque_sp; }

const lldb::BreakpointSP &SBBreakpoint::operator*() const {
  return m_opaque_sp;
}

bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
  return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
         nullptr;
}

BreakpointEventType
SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
  if (event.IsValid())
    return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
        event.GetSP());
  return eBreakpointEventTypeInvalidType;
}

SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
  SBBreakpoint sb_breakpoint;
  if (event.IsValid())
    sb_breakpoint.m_opaque_sp =
        Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP());
  return sb_breakpoint;
}

SBBreakpointLocation
SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
                                                    uint32_t loc_idx) {
  SBBreakpointLocation sb_breakpoint_loc;
  if (event.IsValid())
    sb_breakpoint_loc.SetLocation(
        Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
            event.GetSP(), loc_idx));
  return sb_breakpoint_loc;
}

uint32_t
SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
  uint32_t num_locations = 0;
  if (event.IsValid())
    num_locations =
        (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
            event.GetSP()));
  return num_locations;
}

// This is simple collection of breakpoint id's and their target.
class SBBreakpointListImpl {
public:
  SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() {
    if (target_sp && target_sp->IsValid())
      m_target_wp = target_sp;
  }

  ~SBBreakpointListImpl() = default;

  size_t GetSize() { return m_break_ids.size(); }

  BreakpointSP GetBreakpointAtIndex(size_t idx) {
    if (idx >= m_break_ids.size())
      return BreakpointSP();
    TargetSP target_sp = m_target_wp.lock();
    if (!target_sp)
      return BreakpointSP();
    lldb::break_id_t bp_id = m_break_ids[idx];
    return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
  }

  BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
    TargetSP target_sp = m_target_wp.lock();
    if (!target_sp)
      return BreakpointSP();

    for (lldb::break_id_t &break_id : m_break_ids) {
      if (break_id == desired_id)
        return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
    }
    return BreakpointSP();
  }

  bool Append(Breakpoint &bkpt) {
    TargetSP target_sp = m_target_wp.lock();
    if (!target_sp)
      return false;
    if (bkpt.GetTargetSP() != target_sp)
      return false;
    m_break_ids.push_back(bkpt.GetID());
    return true;
  }

  bool AppendIfUnique(Breakpoint &bkpt) {
    TargetSP target_sp = m_target_wp.lock();
    if (!target_sp)
      return false;
    if (bkpt.GetTargetSP() != target_sp)
      return false;
    lldb::break_id_t bp_id = bkpt.GetID();
    if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) ==
        m_break_ids.end())
      return false;

    m_break_ids.push_back(bkpt.GetID());
    return true;
  }

  bool AppendByID(lldb::break_id_t id) {
    TargetSP target_sp = m_target_wp.lock();
    if (!target_sp)
      return false;
    if (id == LLDB_INVALID_BREAK_ID)
      return false;
    m_break_ids.push_back(id);
    return true;
  }

  void Clear() { m_break_ids.clear(); }

  void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
    for (lldb::break_id_t id : m_break_ids) {
      bp_list.AddBreakpointID(BreakpointID(id));
    }
  }

  TargetSP GetTarget() { return m_target_wp.lock(); }

private:
  std::vector<lldb::break_id_t> m_break_ids;
  TargetWP m_target_wp;
};

SBBreakpointList::SBBreakpointList(SBTarget &target)
    : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {}

SBBreakpointList::~SBBreakpointList() {}

size_t SBBreakpointList::GetSize() const {
  if (!m_opaque_sp)
    return 0;
  else
    return m_opaque_sp->GetSize();
}

SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
  if (!m_opaque_sp)
    return SBBreakpoint();

  BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
  return SBBreakpoint(bkpt_sp);
}

SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
  if (!m_opaque_sp)
    return SBBreakpoint();
  BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
  return SBBreakpoint(bkpt_sp);
}

void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
  if (!sb_bkpt.IsValid())
    return;
  if (!m_opaque_sp)
    return;
  m_opaque_sp->Append(*sb_bkpt.get());
}

void SBBreakpointList::AppendByID(lldb::break_id_t id) {
  if (!m_opaque_sp)
    return;
  m_opaque_sp->AppendByID(id);
}

bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
  if (!sb_bkpt.IsValid())
    return false;
  if (!m_opaque_sp)
    return false;
  return m_opaque_sp->AppendIfUnique(*sb_bkpt.get());
}

void SBBreakpointList::Clear() {
  if (m_opaque_sp)
    m_opaque_sp->Clear();
}

void SBBreakpointList::CopyToBreakpointIDList(
    lldb_private::BreakpointIDList &bp_id_list) {
  if (m_opaque_sp)
    m_opaque_sp->CopyToBreakpointIDList(bp_id_list);
}
