//===-- SBTrace.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 "SBReproducerPrivate.h"
#include "lldb/Target/Process.h"

#include "lldb/API/SBTrace.h"
#include "lldb/API/SBTraceOptions.h"

#include <memory>

using namespace lldb;
using namespace lldb_private;

class TraceImpl {
public:
  lldb::user_id_t uid;
};

lldb::ProcessSP SBTrace::GetSP() const { return m_opaque_wp.lock(); }

size_t SBTrace::GetTraceData(SBError &error, void *buf, size_t size,
                             size_t offset, lldb::tid_t thread_id) {
  LLDB_RECORD_DUMMY(size_t, SBTrace, GetTraceData,
                    (lldb::SBError &, void *, size_t, size_t, lldb::tid_t),
                    error, buf, size, offset, thread_id);

  ProcessSP process_sp(GetSP());
  llvm::MutableArrayRef<uint8_t> buffer(static_cast<uint8_t *>(buf), size);
  error.Clear();

  if (!process_sp) {
    error.SetErrorString("invalid process");
  } else {
    error.SetError(
        process_sp->GetData(GetTraceUID(), thread_id, buffer, offset));
  }
  return buffer.size();
}

size_t SBTrace::GetMetaData(SBError &error, void *buf, size_t size,
                            size_t offset, lldb::tid_t thread_id) {
  LLDB_RECORD_DUMMY(size_t, SBTrace, GetMetaData,
                    (lldb::SBError &, void *, size_t, size_t, lldb::tid_t),
                    error, buf, size, offset, thread_id);

  ProcessSP process_sp(GetSP());
  llvm::MutableArrayRef<uint8_t> buffer(static_cast<uint8_t *>(buf), size);
  error.Clear();

  if (!process_sp) {
    error.SetErrorString("invalid process");
  } else {
    error.SetError(
        process_sp->GetMetaData(GetTraceUID(), thread_id, buffer, offset));
  }
  return buffer.size();
}

void SBTrace::StopTrace(SBError &error, lldb::tid_t thread_id) {
  LLDB_RECORD_METHOD(void, SBTrace, StopTrace, (lldb::SBError &, lldb::tid_t),
                     error, thread_id);

  ProcessSP process_sp(GetSP());
  error.Clear();

  if (!process_sp) {
    error.SetErrorString("invalid process");
    return;
  }
  error.SetError(process_sp->StopTrace(GetTraceUID(), thread_id));
}

void SBTrace::GetTraceConfig(SBTraceOptions &options, SBError &error) {
  error.SetErrorString("deprecated");
}

lldb::user_id_t SBTrace::GetTraceUID() {
  LLDB_RECORD_METHOD_NO_ARGS(lldb::user_id_t, SBTrace, GetTraceUID);

  if (m_trace_impl_sp)
    return m_trace_impl_sp->uid;
  return LLDB_INVALID_UID;
}

void SBTrace::SetTraceUID(lldb::user_id_t uid) {
  if (m_trace_impl_sp)
    m_trace_impl_sp->uid = uid;
}

SBTrace::SBTrace() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBTrace);

  m_trace_impl_sp = std::make_shared<TraceImpl>();
  if (m_trace_impl_sp)
    m_trace_impl_sp->uid = LLDB_INVALID_UID;
}

void SBTrace::SetSP(const ProcessSP &process_sp) { m_opaque_wp = process_sp; }

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

  if (!m_trace_impl_sp)
    return false;
  if (!GetSP())
    return false;
  return true;
}

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBTrace>(Registry &R) {
  LLDB_REGISTER_METHOD(void, SBTrace, StopTrace,
                       (lldb::SBError &, lldb::tid_t));
  LLDB_REGISTER_METHOD(void, SBTrace, GetTraceConfig,
                       (lldb::SBTraceOptions &, lldb::SBError &));
  LLDB_REGISTER_METHOD(lldb::user_id_t, SBTrace, GetTraceUID, ());
  LLDB_REGISTER_CONSTRUCTOR(SBTrace, ());
  LLDB_REGISTER_METHOD(bool, SBTrace, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBTrace, operator bool, ());
}

}
}
