//===-- SBQueueItem.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/lldb-forward.h"

#include "SBReproducerPrivate.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBQueueItem.h"
#include "lldb/API/SBThread.h"
#include "lldb/Core/Address.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/QueueItem.h"
#include "lldb/Target/Thread.h"

using namespace lldb;
using namespace lldb_private;

// Constructors
SBQueueItem::SBQueueItem() : m_queue_item_sp() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBQueueItem);
}

SBQueueItem::SBQueueItem(const QueueItemSP &queue_item_sp)
    : m_queue_item_sp(queue_item_sp) {
  LLDB_RECORD_CONSTRUCTOR(SBQueueItem, (const lldb::QueueItemSP &),
                          queue_item_sp);
}

// Destructor
SBQueueItem::~SBQueueItem() { m_queue_item_sp.reset(); }

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

  return m_queue_item_sp.get() != nullptr;
}

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

  m_queue_item_sp.reset();
}

void SBQueueItem::SetQueueItem(const QueueItemSP &queue_item_sp) {
  LLDB_RECORD_METHOD(void, SBQueueItem, SetQueueItem,
                     (const lldb::QueueItemSP &), queue_item_sp);

  m_queue_item_sp = queue_item_sp;
}

lldb::QueueItemKind SBQueueItem::GetKind() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::QueueItemKind, SBQueueItem, GetKind);

  QueueItemKind result = eQueueItemKindUnknown;
  if (m_queue_item_sp) {
    result = m_queue_item_sp->GetKind();
  }
  return result;
}

void SBQueueItem::SetKind(lldb::QueueItemKind kind) {
  LLDB_RECORD_METHOD(void, SBQueueItem, SetKind, (lldb::QueueItemKind), kind);

  if (m_queue_item_sp) {
    m_queue_item_sp->SetKind(kind);
  }
}

SBAddress SBQueueItem::GetAddress() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBAddress, SBQueueItem, GetAddress);

  SBAddress result;
  if (m_queue_item_sp) {
    result.SetAddress(m_queue_item_sp->GetAddress());
  }
  return LLDB_RECORD_RESULT(result);
}

void SBQueueItem::SetAddress(SBAddress addr) {
  LLDB_RECORD_METHOD(void, SBQueueItem, SetAddress, (lldb::SBAddress), addr);

  if (m_queue_item_sp) {
    m_queue_item_sp->SetAddress(addr.ref());
  }
}

SBThread SBQueueItem::GetExtendedBacktraceThread(const char *type) {
  LLDB_RECORD_METHOD(lldb::SBThread, SBQueueItem, GetExtendedBacktraceThread,
                     (const char *), type);

  SBThread result;
  if (m_queue_item_sp) {
    ProcessSP process_sp = m_queue_item_sp->GetProcessSP();
    Process::StopLocker stop_locker;
    if (process_sp && stop_locker.TryLock(&process_sp->GetRunLock())) {
      ThreadSP thread_sp;
      ConstString type_const(type);
      thread_sp = m_queue_item_sp->GetExtendedBacktraceThread(type_const);
      if (thread_sp) {
        // Save this in the Process' ExtendedThreadList so a strong pointer
        // retains the object
        process_sp->GetExtendedThreadList().AddThread(thread_sp);
        result.SetThread(thread_sp);
      }
    }
  }
  return LLDB_RECORD_RESULT(result);
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBQueueItem>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBQueueItem, ());
  LLDB_REGISTER_CONSTRUCTOR(SBQueueItem, (const lldb::QueueItemSP &));
  LLDB_REGISTER_METHOD_CONST(bool, SBQueueItem, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBQueueItem, operator bool, ());
  LLDB_REGISTER_METHOD(void, SBQueueItem, Clear, ());
  LLDB_REGISTER_METHOD(void, SBQueueItem, SetQueueItem,
                       (const lldb::QueueItemSP &));
  LLDB_REGISTER_METHOD_CONST(lldb::QueueItemKind, SBQueueItem, GetKind, ());
  LLDB_REGISTER_METHOD(void, SBQueueItem, SetKind, (lldb::QueueItemKind));
  LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBQueueItem, GetAddress, ());
  LLDB_REGISTER_METHOD(void, SBQueueItem, SetAddress, (lldb::SBAddress));
  LLDB_REGISTER_METHOD(lldb::SBThread, SBQueueItem,
                       GetExtendedBacktraceThread, (const char *));
}

}
}
