//===-- SBLineEntry.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/API/SBLineEntry.h"
#include "SBReproducerPrivate.h"
#include "Utils.h"
#include "lldb/API/SBStream.h"
#include "lldb/Host/PosixApi.h"
#include "lldb/Symbol/LineEntry.h"
#include "lldb/Utility/StreamString.h"

#include <climits>

using namespace lldb;
using namespace lldb_private;

SBLineEntry::SBLineEntry() : m_opaque_up() {
  LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBLineEntry);
}

SBLineEntry::SBLineEntry(const SBLineEntry &rhs) : m_opaque_up() {
  LLDB_RECORD_CONSTRUCTOR(SBLineEntry, (const lldb::SBLineEntry &), rhs);

  m_opaque_up = clone(rhs.m_opaque_up);
}

SBLineEntry::SBLineEntry(const lldb_private::LineEntry *lldb_object_ptr)
    : m_opaque_up() {
  if (lldb_object_ptr)
    m_opaque_up = std::make_unique<LineEntry>(*lldb_object_ptr);
}

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

  if (this != &rhs)
    m_opaque_up = clone(rhs.m_opaque_up);
  return LLDB_RECORD_RESULT(*this);
}

void SBLineEntry::SetLineEntry(const lldb_private::LineEntry &lldb_object_ref) {
  m_opaque_up = std::make_unique<LineEntry>(lldb_object_ref);
}

SBLineEntry::~SBLineEntry() = default;

SBAddress SBLineEntry::GetStartAddress() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBAddress, SBLineEntry,
                                   GetStartAddress);

  SBAddress sb_address;
  if (m_opaque_up)
    sb_address.SetAddress(m_opaque_up->range.GetBaseAddress());

  return LLDB_RECORD_RESULT(sb_address);
}

SBAddress SBLineEntry::GetEndAddress() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBAddress, SBLineEntry, GetEndAddress);

  SBAddress sb_address;
  if (m_opaque_up) {
    sb_address.SetAddress(m_opaque_up->range.GetBaseAddress());
    sb_address.OffsetAddress(m_opaque_up->range.GetByteSize());
  }
  return LLDB_RECORD_RESULT(sb_address);
}

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

  return m_opaque_up.get() && m_opaque_up->IsValid();
}

SBFileSpec SBLineEntry::GetFileSpec() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBFileSpec, SBLineEntry, GetFileSpec);

  SBFileSpec sb_file_spec;
  if (m_opaque_up.get() && m_opaque_up->file)
    sb_file_spec.SetFileSpec(m_opaque_up->file);

  return LLDB_RECORD_RESULT(sb_file_spec);
}

uint32_t SBLineEntry::GetLine() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBLineEntry, GetLine);

  uint32_t line = 0;
  if (m_opaque_up)
    line = m_opaque_up->line;

  return line;
}

uint32_t SBLineEntry::GetColumn() const {
  LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBLineEntry, GetColumn);

  if (m_opaque_up)
    return m_opaque_up->column;
  return 0;
}

void SBLineEntry::SetFileSpec(lldb::SBFileSpec filespec) {
  LLDB_RECORD_METHOD(void, SBLineEntry, SetFileSpec, (lldb::SBFileSpec),
                     filespec);

  if (filespec.IsValid())
    ref().file = filespec.ref();
  else
    ref().file.Clear();
}
void SBLineEntry::SetLine(uint32_t line) {
  LLDB_RECORD_METHOD(void, SBLineEntry, SetLine, (uint32_t), line);

  ref().line = line;
}

void SBLineEntry::SetColumn(uint32_t column) {
  LLDB_RECORD_METHOD(void, SBLineEntry, SetColumn, (uint32_t), column);

  ref().line = column;
}

bool SBLineEntry::operator==(const SBLineEntry &rhs) const {
  LLDB_RECORD_METHOD_CONST(
      bool, SBLineEntry, operator==,(const lldb::SBLineEntry &), rhs);

  lldb_private::LineEntry *lhs_ptr = m_opaque_up.get();
  lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_up.get();

  if (lhs_ptr && rhs_ptr)
    return lldb_private::LineEntry::Compare(*lhs_ptr, *rhs_ptr) == 0;

  return lhs_ptr == rhs_ptr;
}

bool SBLineEntry::operator!=(const SBLineEntry &rhs) const {
  LLDB_RECORD_METHOD_CONST(
      bool, SBLineEntry, operator!=,(const lldb::SBLineEntry &), rhs);

  lldb_private::LineEntry *lhs_ptr = m_opaque_up.get();
  lldb_private::LineEntry *rhs_ptr = rhs.m_opaque_up.get();

  if (lhs_ptr && rhs_ptr)
    return lldb_private::LineEntry::Compare(*lhs_ptr, *rhs_ptr) != 0;

  return lhs_ptr != rhs_ptr;
}

const lldb_private::LineEntry *SBLineEntry::operator->() const {
  return m_opaque_up.get();
}

lldb_private::LineEntry &SBLineEntry::ref() {
  if (m_opaque_up == nullptr)
    m_opaque_up = std::make_unique<lldb_private::LineEntry>();
  return *m_opaque_up;
}

const lldb_private::LineEntry &SBLineEntry::ref() const { return *m_opaque_up; }

bool SBLineEntry::GetDescription(SBStream &description) {
  LLDB_RECORD_METHOD(bool, SBLineEntry, GetDescription, (lldb::SBStream &),
                     description);

  Stream &strm = description.ref();

  if (m_opaque_up) {
    char file_path[PATH_MAX * 2];
    m_opaque_up->file.GetPath(file_path, sizeof(file_path));
    strm.Printf("%s:%u", file_path, GetLine());
    if (GetColumn() > 0)
      strm.Printf(":%u", GetColumn());
  } else
    strm.PutCString("No value");

  return true;
}

lldb_private::LineEntry *SBLineEntry::get() { return m_opaque_up.get(); }

namespace lldb_private {
namespace repro {

template <>
void RegisterMethods<SBLineEntry>(Registry &R) {
  LLDB_REGISTER_CONSTRUCTOR(SBLineEntry, ());
  LLDB_REGISTER_CONSTRUCTOR(SBLineEntry, (const lldb::SBLineEntry &));
  LLDB_REGISTER_METHOD(const lldb::SBLineEntry &,
                       SBLineEntry, operator=,(const lldb::SBLineEntry &));
  LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBLineEntry, GetStartAddress,
                             ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBAddress, SBLineEntry, GetEndAddress, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBLineEntry, IsValid, ());
  LLDB_REGISTER_METHOD_CONST(bool, SBLineEntry, operator bool, ());
  LLDB_REGISTER_METHOD_CONST(lldb::SBFileSpec, SBLineEntry, GetFileSpec, ());
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBLineEntry, GetLine, ());
  LLDB_REGISTER_METHOD_CONST(uint32_t, SBLineEntry, GetColumn, ());
  LLDB_REGISTER_METHOD(void, SBLineEntry, SetFileSpec, (lldb::SBFileSpec));
  LLDB_REGISTER_METHOD(void, SBLineEntry, SetLine, (uint32_t));
  LLDB_REGISTER_METHOD(void, SBLineEntry, SetColumn, (uint32_t));
  LLDB_REGISTER_METHOD_CONST(
      bool, SBLineEntry, operator==,(const lldb::SBLineEntry &));
  LLDB_REGISTER_METHOD_CONST(
      bool, SBLineEntry, operator!=,(const lldb::SBLineEntry &));
  LLDB_REGISTER_METHOD(bool, SBLineEntry, GetDescription, (lldb::SBStream &));
}

}
}
