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

#include "lldb/API/SBBreakpoint.h"
#include "SBReproducerPrivate.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/BreakpointResolver.h"
#include "lldb/Breakpoint/BreakpointResolverScripted.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Debugger.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/Utility/Stream.h"

#include "SBBreakpointOptionCommon.h"

#include "lldb/lldb-enumerations.h"

#include "llvm/ADT/STLExtras.h"

using namespace lldb;
using namespace lldb_private;

SBBreakpoint::SBBreakpoint() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBBreakpoint); }

SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
    : m_opaque_wp(rhs.m_opaque_wp) {
  LLDB_RECORD_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &), rhs);
}

SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
    : m_opaque_wp(bp_sp) {
  LLDB_RECORD_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &), bp_sp);
}

SBBreakpoint::~SBBreakpoint() = default;

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

  m_opaque_wp = rhs.m_opaque_wp;
  return LLDB_RECORD_RESULT(*this);
}

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

  return m_opaque_wp.lock() == rhs.m_opaque_wp.lock();
}

bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
  LLDB_RECORD_METHOD(
      bool, SBBreakpoint, operator!=,(const lldb::SBBreakpoint &), rhs);

  return m_opaque_wp.lock() != rhs.m_opaque_wp.lock();
}

break_id_t SBBreakpoint::GetID() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::break_id_t, SBBreakpoint, GetID);

  break_id_t break_id = LLDB_INVALID_BREAK_ID;
  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp)
    break_id = bkpt_sp->GetID();

  return break_id;
}

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

  BreakpointSP bkpt_sp = GetSP();
  if (!bkpt_sp)
    return false;
  else if (bkpt_sp->GetTarget().GetBreakpointByID(bkpt_sp->GetID()))
    return true;
  else
    return false;
}

void SBBreakpoint::ClearAllBreakpointSites() {
  LLDB_RECORD_METHOD_NO_ARGS(void, SBBreakpoint, ClearAllBreakpointSites);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    bkpt_sp->ClearAllBreakpointSites();
  }
}

SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
  LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint,
                     FindLocationByAddress, (lldb::addr_t), vm_addr);

  SBBreakpointLocation sb_bp_location;

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

break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
  LLDB_RECORD_METHOD(lldb::break_id_t, SBBreakpoint, FindLocationIDByAddress,
                     (lldb::addr_t), vm_addr);

  break_id_t break_id = LLDB_INVALID_BREAK_ID;
  BreakpointSP bkpt_sp = GetSP();

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

  return break_id;
}

SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
  LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint, FindLocationByID,
                     (lldb::break_id_t), bp_loc_id);

  SBBreakpointLocation sb_bp_location;
  BreakpointSP bkpt_sp = GetSP();

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

  return LLDB_RECORD_RESULT(sb_bp_location);
}

SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
  LLDB_RECORD_METHOD(lldb::SBBreakpointLocation, SBBreakpoint,
                     GetLocationAtIndex, (uint32_t), index);

  SBBreakpointLocation sb_bp_location;
  BreakpointSP bkpt_sp = GetSP();

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

  return LLDB_RECORD_RESULT(sb_bp_location);
}

void SBBreakpoint::SetEnabled(bool enable) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetEnabled, (bool), enable);

  BreakpointSP bkpt_sp = GetSP();

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

bool SBBreakpoint::IsEnabled() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, IsEnabled);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    return bkpt_sp->IsEnabled();
  } else
    return false;
}

void SBBreakpoint::SetOneShot(bool one_shot) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetOneShot, (bool), one_shot);

  BreakpointSP bkpt_sp = GetSP();

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

bool SBBreakpoint::IsOneShot() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsOneShot);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    return bkpt_sp->IsOneShot();
  } else
    return false;
}

bool SBBreakpoint::IsInternal() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, IsInternal);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    return bkpt_sp->IsInternal();
  } else
    return false;
}

void SBBreakpoint::SetIgnoreCount(uint32_t count) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t), count);

  BreakpointSP bkpt_sp = GetSP();

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

void SBBreakpoint::SetCondition(const char *condition) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetCondition, (const char *),
                     condition);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    bkpt_sp->SetCondition(condition);
  }
}

const char *SBBreakpoint::GetCondition() {
  LLDB_RECORD_METHOD_NO_ARGS(const char *, SBBreakpoint, GetCondition);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    return bkpt_sp->GetConditionText();
  }
  return nullptr;
}

void SBBreakpoint::SetAutoContinue(bool auto_continue) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetAutoContinue, (bool),
                     auto_continue);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    bkpt_sp->SetAutoContinue(auto_continue);
  }
}

bool SBBreakpoint::GetAutoContinue() {
  LLDB_RECORD_METHOD_NO_ARGS(bool, SBBreakpoint, GetAutoContinue);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    return bkpt_sp->IsAutoContinue();
  }
  return false;
}

uint32_t SBBreakpoint::GetHitCount() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetHitCount);

  uint32_t count = 0;
  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    count = bkpt_sp->GetHitCount();
  }

  return count;
}

uint32_t SBBreakpoint::GetIgnoreCount() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetIgnoreCount);

  uint32_t count = 0;
  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    count = bkpt_sp->GetIgnoreCount();
  }

  return count;
}

void SBBreakpoint::SetThreadID(tid_t tid) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t), tid);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    bkpt_sp->SetThreadID(tid);
  }
}

tid_t SBBreakpoint::GetThreadID() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::tid_t, SBBreakpoint, GetThreadID);

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

  return tid;
}

void SBBreakpoint::SetThreadIndex(uint32_t index) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t), index);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    bkpt_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
  }
}

uint32_t SBBreakpoint::GetThreadIndex() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBBreakpoint, GetThreadIndex);

  uint32_t thread_idx = UINT32_MAX;
  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    const ThreadSpec *thread_spec =
        bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
    if (thread_spec != nullptr)
      thread_idx = thread_spec->GetIndex();
  }

  return thread_idx;
}

void SBBreakpoint::SetThreadName(const char *thread_name) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetThreadName, (const char *),
                     thread_name);

  BreakpointSP bkpt_sp = GetSP();

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

const char *SBBreakpoint::GetThreadName() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpoint, GetThreadName);

  const char *name = nullptr;
  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    const ThreadSpec *thread_spec =
        bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
    if (thread_spec != nullptr)
      name = thread_spec->GetName();
  }

  return name;
}

void SBBreakpoint::SetQueueName(const char *queue_name) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetQueueName, (const char *),
                     queue_name);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    bkpt_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
  }
}

const char *SBBreakpoint::GetQueueName() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBBreakpoint, GetQueueName);

  const char *name = nullptr;
  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    const ThreadSpec *thread_spec =
        bkpt_sp->GetOptions()->GetThreadSpecNoCreate();
    if (thread_spec)
      name = thread_spec->GetQueueName();
  }

  return name;
}

size_t SBBreakpoint::GetNumResolvedLocations() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpoint,
                                   GetNumResolvedLocations);

  size_t num_resolved = 0;
  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    num_resolved = bkpt_sp->GetNumResolvedLocations();
  }
  return num_resolved;
}

size_t SBBreakpoint::GetNumLocations() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpoint, GetNumLocations);

  BreakpointSP bkpt_sp = GetSP();
  size_t num_locs = 0;
  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    num_locs = bkpt_sp->GetNumLocations();
  }
  return num_locs;
}

void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetCommandLineCommands,
                     (lldb::SBStringList &), commands);

  BreakpointSP bkpt_sp = GetSP();
  if (!bkpt_sp)
    return;
  if (commands.GetSize() == 0)
    return;

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

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

bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
  LLDB_RECORD_METHOD(bool, SBBreakpoint, GetCommandLineCommands,
                     (lldb::SBStringList &), commands);

  BreakpointSP bkpt_sp = GetSP();
  if (!bkpt_sp)
    return false;
  StringList command_list;
  bool has_commands =
      bkpt_sp->GetOptions()->GetCommandLineCallbacks(command_list);
  if (has_commands)
    commands.AppendList(command_list);
  return has_commands;
}

bool SBBreakpoint::GetDescription(SBStream &s) {
  LLDB_RECORD_METHOD(bool, SBBreakpoint, GetDescription, (lldb::SBStream &), s);

  return GetDescription(s, true);
}

bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
  LLDB_RECORD_METHOD(bool, SBBreakpoint, GetDescription,
                     (lldb::SBStream &, bool), s, include_locations);

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

SBError SBBreakpoint::AddLocation(SBAddress &address) {
  LLDB_RECORD_METHOD(lldb::SBError, SBBreakpoint, AddLocation,
                     (lldb::SBAddress &), address);

  BreakpointSP bkpt_sp = GetSP();
  SBError error;

  if (!address.IsValid()) {
    error.SetErrorString("Can't add an invalid address.");
    return LLDB_RECORD_RESULT(error);
  }

  if (!bkpt_sp) {
    error.SetErrorString("No breakpoint to add a location to.");
    return LLDB_RECORD_RESULT(error);
  }

  if (!llvm::isa<BreakpointResolverScripted>(bkpt_sp->GetResolver().get())) {
    error.SetErrorString("Only a scripted resolver can add locations.");
    return LLDB_RECORD_RESULT(error);
  }

  if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref()))
    bkpt_sp->AddLocation(address.ref());
  else {
    StreamString s;
    address.get()->Dump(&s, &bkpt_sp->GetTarget(),
                        Address::DumpStyleModuleWithFileAddress);
    error.SetErrorStringWithFormat("Address: %s didn't pass the filter.",
                                   s.GetData());
  }
  return LLDB_RECORD_RESULT(error);
}

void SBBreakpoint ::SetCallback(SBBreakpointHitCallback callback, void *baton) {
  LLDB_RECORD_DUMMY(void, SBBreakpoint, SetCallback,
                    (lldb::SBBreakpointHitCallback, void *), callback, baton);

  BreakpointSP bkpt_sp = GetSP();

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

void SBBreakpoint::SetScriptCallbackFunction(
    const char *callback_function_name) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, SetScriptCallbackFunction,
                     (const char *), callback_function_name);

  BreakpointSP bkpt_sp = GetSP();

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

SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
  LLDB_RECORD_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody,
                     (const char *), callback_body_text);

  BreakpointSP bkpt_sp = GetSP();

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

  return LLDB_RECORD_RESULT(sb_error);
}

bool SBBreakpoint::AddName(const char *new_name) {
  LLDB_RECORD_METHOD(bool, SBBreakpoint, AddName, (const char *), new_name);

  BreakpointSP bkpt_sp = GetSP();

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

  return true;
}

void SBBreakpoint::RemoveName(const char *name_to_remove) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, RemoveName, (const char *),
                     name_to_remove);

  BreakpointSP bkpt_sp = GetSP();

  if (bkpt_sp) {
    std::lock_guard<std::recursive_mutex> guard(
        bkpt_sp->GetTarget().GetAPIMutex());
    bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,
                                                  ConstString(name_to_remove));
  }
}

bool SBBreakpoint::MatchesName(const char *name) {
  LLDB_RECORD_METHOD(bool, SBBreakpoint, MatchesName, (const char *), name);

  BreakpointSP bkpt_sp = GetSP();

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

  return false;
}

void SBBreakpoint::GetNames(SBStringList &names) {
  LLDB_RECORD_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &),
                     names);

  BreakpointSP bkpt_sp = GetSP();

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

bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent,
                            (const lldb::SBEvent &), event);

  return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
         nullptr;
}

BreakpointEventType
SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint,
                            GetBreakpointEventTypeFromEvent,
                            (const lldb::SBEvent &), event);

  if (event.IsValid())
    return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
        event.GetSP());
  return eBreakpointEventTypeInvalidType;
}

SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint,
                            GetBreakpointFromEvent, (const lldb::SBEvent &),
                            event);

  if (event.IsValid())
    return LLDB_RECORD_RESULT(
        SBBreakpoint(Breakpoint::BreakpointEventData::GetBreakpointFromEvent(
            event.GetSP())));
  return LLDB_RECORD_RESULT(SBBreakpoint());
}

SBBreakpointLocation
SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
                                                    uint32_t loc_idx) {
  LLDB_RECORD_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint,
                            GetBreakpointLocationAtIndexFromEvent,
                            (const lldb::SBEvent &, uint32_t), event, loc_idx);

  SBBreakpointLocation sb_breakpoint_loc;
  if (event.IsValid())
    sb_breakpoint_loc.SetLocation(
        Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
            event.GetSP(), loc_idx));
  return LLDB_RECORD_RESULT(sb_breakpoint_loc);
}

uint32_t
SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
  LLDB_RECORD_STATIC_METHOD(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;
}

bool SBBreakpoint::IsHardware() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBBreakpoint, IsHardware);

  BreakpointSP bkpt_sp = GetSP();
  if (bkpt_sp)
    return bkpt_sp->IsHardware();
  return false;
}

BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); }

// 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(BreakpointSP bkpt) {
    TargetSP target_sp = m_target_wp.lock();
    if (!target_sp || !bkpt)
      return false;
    if (bkpt->GetTargetSP() != target_sp)
      return false;
    m_break_ids.push_back(bkpt->GetID());
    return true;
  }

  bool AppendIfUnique(BreakpointSP bkpt) {
    TargetSP target_sp = m_target_wp.lock();
    if (!target_sp || !bkpt)
      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())) {
  LLDB_RECORD_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &), target);
}

SBBreakpointList::~SBBreakpointList() {}

size_t SBBreakpointList::GetSize() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(size_t, SBBreakpointList, GetSize);

  if (!m_opaque_sp)
    return 0;
  else
    return m_opaque_sp->GetSize();
}

SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, GetBreakpointAtIndex,
                     (size_t), idx);

  if (!m_opaque_sp)
    return LLDB_RECORD_RESULT(SBBreakpoint());

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

SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
  LLDB_RECORD_METHOD(lldb::SBBreakpoint, SBBreakpointList, FindBreakpointByID,
                     (lldb::break_id_t), id);

  if (!m_opaque_sp)
    return LLDB_RECORD_RESULT(SBBreakpoint());
  BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
  return LLDB_RECORD_RESULT(SBBreakpoint(bkpt_sp));
}

void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
  LLDB_RECORD_METHOD(void, SBBreakpointList, Append,
                     (const lldb::SBBreakpoint &), sb_bkpt);

  if (!sb_bkpt.IsValid())
    return;
  if (!m_opaque_sp)
    return;
  m_opaque_sp->Append(sb_bkpt.m_opaque_wp.lock());
}

void SBBreakpointList::AppendByID(lldb::break_id_t id) {
  LLDB_RECORD_METHOD(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) {
  LLDB_RECORD_METHOD(bool, SBBreakpointList, AppendIfUnique,
                     (const lldb::SBBreakpoint &), sb_bkpt);

  if (!sb_bkpt.IsValid())
    return false;
  if (!m_opaque_sp)
    return false;
  return m_opaque_sp->AppendIfUnique(sb_bkpt.GetSP());
}

void SBBreakpointList::Clear() {
  LLDB_RECORD_METHOD_NO_ARGS(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);
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBBreakpoint>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, ());
  LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::SBBreakpoint &));
  LLDB_REGISTER_CONSTRUCTOR(SBBreakpoint, (const lldb::BreakpointSP &));
  LLDB_REGISTER_METHOD(const lldb::SBBreakpoint &,
                       SBBreakpoint, operator=,(const lldb::SBBreakpoint &));
  LLDB_REGISTER_METHOD(bool,
                       SBBreakpoint, operator==,(const lldb::SBBreakpoint &));
  LLDB_REGISTER_METHOD(bool,
                       SBBreakpoint, operator!=,(const lldb::SBBreakpoint &));
  LLDB_REGISTER_METHOD_CONST(lldb::break_id_t, SBBreakpoint, GetID, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, operator bool, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, ClearAllBreakpointSites, ());
  LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint,
                       FindLocationByAddress, (lldb::addr_t));
  LLDB_REGISTER_METHOD(lldb::break_id_t, SBBreakpoint,
                       FindLocationIDByAddress, (lldb::addr_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint,
                       FindLocationByID, (lldb::break_id_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpointLocation, SBBreakpoint,
                       GetLocationAtIndex, (uint32_t));
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetEnabled, (bool));
  LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsEnabled, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetOneShot, (bool));
  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsOneShot, ());
  LLDB_REGISTER_METHOD(bool, SBBreakpoint, IsInternal, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetIgnoreCount, (uint32_t));
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCondition, (const char *));
  LLDB_REGISTER_METHOD(const char *, SBBreakpoint, GetCondition, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetAutoContinue, (bool));
  LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetAutoContinue, ());
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetHitCount, ());
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetIgnoreCount, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadID, (lldb::tid_t));
  LLDB_REGISTER_METHOD(lldb::tid_t, SBBreakpoint, GetThreadID, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadIndex, (uint32_t));
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBBreakpoint, GetThreadIndex, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetThreadName, (const char *));
  LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetThreadName, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetQueueName, (const char *));
  LLDB_REGISTER_METHOD_CONST(const char *, SBBreakpoint, GetQueueName, ());
  LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumResolvedLocations,
                             ());
  LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpoint, GetNumLocations, ());
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetCommandLineCommands,
                       (lldb::SBStringList &));
  LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetCommandLineCommands,
                       (lldb::SBStringList &));
  LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription,
                       (lldb::SBStream &));
  LLDB_REGISTER_METHOD(bool, SBBreakpoint, GetDescription,
                       (lldb::SBStream &, bool));
  LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, AddLocation,
                       (lldb::SBAddress &));
  LLDB_REGISTER_METHOD(void, SBBreakpoint, SetScriptCallbackFunction,
                       (const char *));
  LLDB_REGISTER_METHOD(lldb::SBError, SBBreakpoint, SetScriptCallbackBody,
                       (const char *));
  LLDB_REGISTER_METHOD(bool, SBBreakpoint, AddName, (const char *));
  LLDB_REGISTER_METHOD(void, SBBreakpoint, RemoveName, (const char *));
  LLDB_REGISTER_METHOD(bool, SBBreakpoint, MatchesName, (const char *));
  LLDB_REGISTER_METHOD(void, SBBreakpoint, GetNames, (lldb::SBStringList &));
  LLDB_REGISTER_STATIC_METHOD(bool, SBBreakpoint, EventIsBreakpointEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_STATIC_METHOD(lldb::BreakpointEventType, SBBreakpoint,
                              GetBreakpointEventTypeFromEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpoint, SBBreakpoint,
                              GetBreakpointFromEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_STATIC_METHOD(lldb::SBBreakpointLocation, SBBreakpoint,
                              GetBreakpointLocationAtIndexFromEvent,
                              (const lldb::SBEvent &, uint32_t));
  LLDB_REGISTER_STATIC_METHOD(uint32_t, SBBreakpoint,
                              GetNumBreakpointLocationsFromEvent,
                              (const lldb::SBEvent &));
  LLDB_REGISTER_METHOD_CONST(bool, SBBreakpoint, IsHardware, ());
}

template <>
void RegisterMethods<SBBreakpointList>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBBreakpointList, (lldb::SBTarget &));
  LLDB_REGISTER_METHOD_CONST(size_t, SBBreakpointList, GetSize, ());
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList,
                       GetBreakpointAtIndex, (size_t));
  LLDB_REGISTER_METHOD(lldb::SBBreakpoint, SBBreakpointList,
                       FindBreakpointByID, (lldb::break_id_t));
  LLDB_REGISTER_METHOD(void, SBBreakpointList, Append,
                       (const lldb::SBBreakpoint &));
  LLDB_REGISTER_METHOD(void, SBBreakpointList, AppendByID,
                       (lldb::break_id_t));
  LLDB_REGISTER_METHOD(bool, SBBreakpointList, AppendIfUnique,
                       (const lldb::SBBreakpoint &));
  LLDB_REGISTER_METHOD(void, SBBreakpointList, Clear, ());
}

}
}
