//===-- PTDecoder.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 "PTDecoder.h"
#include "Decoder.h"

using namespace ptdecoder;
using namespace ptdecoder_private;

// PTInstruction class member functions definitions
PTInstruction::PTInstruction(
    const std::shared_ptr<ptdecoder_private::Instruction> &ptr)
    : m_opaque_sp(ptr) {}

PTInstruction::~PTInstruction() {}

uint64_t PTInstruction::GetInsnAddress() const {
  return (m_opaque_sp ? m_opaque_sp->GetInsnAddress() : 0);
}

size_t PTInstruction::GetRawBytes(void *buf, size_t size) const {
  return (m_opaque_sp ? m_opaque_sp->GetRawBytes(buf, size) : 0);
}

std::string PTInstruction::GetError() const {
  return (m_opaque_sp ? m_opaque_sp->GetError() : "null pointer");
}

bool PTInstruction::GetSpeculative() const {
  return (m_opaque_sp ? m_opaque_sp->GetSpeculative() : 0);
}

// PTInstructionList class member functions definitions
size_t PTInstructionList::GetSize() const {
  return (m_opaque_sp ? m_opaque_sp->GetSize() : 0);
}

PTInstruction PTInstructionList::GetInstructionAtIndex(uint32_t idx) {
  if (m_opaque_sp)
    return PTInstruction(std::shared_ptr<ptdecoder_private::Instruction>(
        new Instruction(m_opaque_sp->GetInstructionAtIndex(idx))));

  return PTInstruction(std::shared_ptr<ptdecoder_private::Instruction>(
      new Instruction("invalid instruction")));
}

void PTInstructionList::SetSP(
    const std::shared_ptr<ptdecoder_private::InstructionList> &ptr) {
  m_opaque_sp = ptr;
}
void PTInstructionList::Clear() {
  if (!m_opaque_sp)
    return;
  m_opaque_sp.reset();
}

// PTTraceOptions class member functions definitions
lldb::TraceType PTTraceOptions::GetType() const {
  return (m_opaque_sp ? m_opaque_sp->getType()
                      : lldb::TraceType::eTraceTypeNone);
}

uint64_t PTTraceOptions::GetTraceBufferSize() const {
  return (m_opaque_sp ? m_opaque_sp->getTraceBufferSize() : 0);
}

uint64_t PTTraceOptions::GetMetaDataBufferSize() const {
  return (m_opaque_sp ? m_opaque_sp->getMetaDataBufferSize() : 0);
}

lldb::SBStructuredData PTTraceOptions::GetTraceParams(lldb::SBError &error) {
  if (!m_opaque_sp)
    error.SetErrorString("null pointer");
  return (m_opaque_sp ? m_opaque_sp->getTraceParams(error)
                      : lldb::SBStructuredData());
}

void PTTraceOptions::SetSP(
    const std::shared_ptr<ptdecoder_private::TraceOptions> &ptr) {
  m_opaque_sp = ptr;
}

// PTDecoder class member functions definitions
PTDecoder::PTDecoder(lldb::SBDebugger &sbdebugger)
    : m_opaque_sp(new ptdecoder_private::Decoder(sbdebugger)) {}

void PTDecoder::StartProcessorTrace(lldb::SBProcess &sbprocess,
                                    lldb::SBTraceOptions &sbtraceoptions,
                                    lldb::SBError &sberror) {
  if (m_opaque_sp == nullptr) {
    sberror.SetErrorStringWithFormat("invalid PTDecoder instance");
    return;
  }

  m_opaque_sp->StartProcessorTrace(sbprocess, sbtraceoptions, sberror);
}

void PTDecoder::StopProcessorTrace(lldb::SBProcess &sbprocess,
                                   lldb::SBError &sberror, lldb::tid_t tid) {
  if (m_opaque_sp == nullptr) {
    sberror.SetErrorStringWithFormat("invalid PTDecoder instance");
    return;
  }

  m_opaque_sp->StopProcessorTrace(sbprocess, sberror, tid);
}

void PTDecoder::GetInstructionLogAtOffset(lldb::SBProcess &sbprocess,
                                          lldb::tid_t tid, uint32_t offset,
                                          uint32_t count,
                                          PTInstructionList &result_list,
                                          lldb::SBError &sberror) {
  if (m_opaque_sp == nullptr) {
    sberror.SetErrorStringWithFormat("invalid PTDecoder instance");
    return;
  }

  std::shared_ptr<ptdecoder_private::InstructionList> insn_list_ptr(
      new InstructionList());
  m_opaque_sp->GetInstructionLogAtOffset(sbprocess, tid, offset, count,
                                         *insn_list_ptr, sberror);
  if (!sberror.Success())
    return;

  result_list.SetSP(insn_list_ptr);
}

void PTDecoder::GetProcessorTraceInfo(lldb::SBProcess &sbprocess,
                                      lldb::tid_t tid, PTTraceOptions &options,
                                      lldb::SBError &sberror) {
  if (m_opaque_sp == nullptr) {
    sberror.SetErrorStringWithFormat("invalid PTDecoder instance");
    return;
  }

  std::shared_ptr<ptdecoder_private::TraceOptions> trace_options_ptr(
      new TraceOptions());
  m_opaque_sp->GetProcessorTraceInfo(sbprocess, tid, *trace_options_ptr,
                                     sberror);
  if (!sberror.Success())
    return;

  options.SetSP(trace_options_ptr);
}
