//===-- LibStdcpp.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 "LibStdcpp.h"
#include "LibCxx.h"

#include "Plugins/Language/CPlusPlus/Generic.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.h"
#include "lldb/DataFormatters/VectorIterator.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

namespace {

class LibstdcppMapIteratorSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
  /*
   (std::_Rb_tree_iterator<std::pair<const int, std::basic_string<char,
   std::char_traits<char>, std::allocator<char> > > >) ibeg = {
   (_Base_ptr) _M_node = 0x0000000100103910 {
   (std::_Rb_tree_color) _M_color = _S_black
   (std::_Rb_tree_node_base::_Base_ptr) _M_parent = 0x00000001001038c0
   (std::_Rb_tree_node_base::_Base_ptr) _M_left = 0x0000000000000000
   (std::_Rb_tree_node_base::_Base_ptr) _M_right = 0x0000000000000000
   }
   }
   */

public:
  explicit LibstdcppMapIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

  llvm::Expected<uint32_t> CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;

private:
  ExecutionContextRef m_exe_ctx_ref;
  lldb::addr_t m_pair_address = 0;
  CompilerType m_pair_type;
  lldb::ValueObjectSP m_pair_sp;
};

class LibStdcppSharedPtrSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  explicit LibStdcppSharedPtrSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

  llvm::Expected<uint32_t> CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;

private:

  // The lifetime of a ValueObject and all its derivative ValueObjects
  // (children, clones, etc.) is managed by a ClusterManager. These
  // objects are only destroyed when every shared pointer to any of them
  // is destroyed, so we must not store a shared pointer to any ValueObject
  // derived from our backend ValueObject (since we're in the same cluster).
  ValueObject *m_ptr_obj = nullptr; // Underlying pointer (held, not owned)
};

} // end of anonymous namespace

LibstdcppMapIteratorSyntheticFrontEnd::LibstdcppMapIteratorSyntheticFrontEnd(
    lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_pair_type(),
      m_pair_sp() {
  if (valobj_sp)
    Update();
}

lldb::ChildCacheState LibstdcppMapIteratorSyntheticFrontEnd::Update() {
  ValueObjectSP valobj_sp = m_backend.GetSP();
  if (!valobj_sp)
    return lldb::ChildCacheState::eRefetch;

  TargetSP target_sp(valobj_sp->GetTargetSP());

  if (!target_sp)
    return lldb::ChildCacheState::eRefetch;

  bool is_64bit = (target_sp->GetArchitecture().GetAddressByteSize() == 8);

  if (!valobj_sp)
    return lldb::ChildCacheState::eRefetch;
  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();

  ValueObjectSP _M_node_sp(valobj_sp->GetChildMemberWithName("_M_node"));
  if (!_M_node_sp)
    return lldb::ChildCacheState::eRefetch;

  m_pair_address = _M_node_sp->GetValueAsUnsigned(0);
  if (m_pair_address == 0)
    return lldb::ChildCacheState::eRefetch;

  m_pair_address += (is_64bit ? 32 : 16);

  CompilerType my_type(valobj_sp->GetCompilerType());
  if (my_type.GetNumTemplateArguments() >= 1) {
    CompilerType pair_type = my_type.GetTypeTemplateArgument(0);
    if (!pair_type)
      return lldb::ChildCacheState::eRefetch;
    m_pair_type = pair_type;
  } else
    return lldb::ChildCacheState::eRefetch;

  return lldb::ChildCacheState::eReuse;
}

llvm::Expected<uint32_t>
LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren() {
  return 2;
}

lldb::ValueObjectSP
LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) {
  if (m_pair_address != 0 && m_pair_type) {
    if (!m_pair_sp)
      m_pair_sp = CreateValueObjectFromAddress("pair", m_pair_address,
                                               m_exe_ctx_ref, m_pair_type);
    if (m_pair_sp)
      return m_pair_sp->GetChildAtIndex(idx);
  }
  return lldb::ValueObjectSP();
}

llvm::Expected<size_t>
LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName(
    ConstString name) {
  if (name == "first")
    return 0;
  if (name == "second")
    return 1;
  return llvm::createStringError("Type has no child named '%s'",
                                 name.AsCString());
}

SyntheticChildrenFrontEnd *
lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  return (valobj_sp ? new LibstdcppMapIteratorSyntheticFrontEnd(valobj_sp)
                    : nullptr);
}

/*
 (lldb) fr var ibeg --ptr-depth 1
 (__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >)
 ibeg = {
 _M_current = 0x00000001001037a0 {
 *_M_current = 1
 }
 }
 */

SyntheticChildrenFrontEnd *
lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  return (valobj_sp ? new VectorIteratorSyntheticFrontEnd(
                          valobj_sp, {ConstString("_M_current")})
                    : nullptr);
}

lldb_private::formatters::VectorIteratorSyntheticFrontEnd::
    VectorIteratorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp,
                                    llvm::ArrayRef<ConstString> item_names)
    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(),
      m_item_names(item_names), m_item_sp() {
  if (valobj_sp)
    Update();
}

lldb::ChildCacheState VectorIteratorSyntheticFrontEnd::Update() {
  m_item_sp.reset();

  ValueObjectSP valobj_sp = m_backend.GetSP();
  if (!valobj_sp)
    return lldb::ChildCacheState::eRefetch;

  ValueObjectSP item_ptr =
      formatters::GetChildMemberWithName(*valobj_sp, m_item_names);
  if (!item_ptr)
    return lldb::ChildCacheState::eRefetch;
  if (item_ptr->GetValueAsUnsigned(0) == 0)
    return lldb::ChildCacheState::eRefetch;
  Status err;
  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
  m_item_sp = CreateValueObjectFromAddress(
      "item", item_ptr->GetValueAsUnsigned(0), m_exe_ctx_ref,
      item_ptr->GetCompilerType().GetPointeeType());
  if (err.Fail())
    m_item_sp.reset();
  return lldb::ChildCacheState::eRefetch;
}

llvm::Expected<uint32_t>
VectorIteratorSyntheticFrontEnd::CalculateNumChildren() {
  return 1;
}

lldb::ValueObjectSP
VectorIteratorSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) {
  if (idx == 0)
    return m_item_sp;
  return lldb::ValueObjectSP();
}

llvm::Expected<size_t>
VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) {
  if (name == "item")
    return 0;
  return llvm::createStringError("Type has no child named '%s'",
                                 name.AsCString());
}

bool lldb_private::formatters::LibStdcppStringSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  ValueObjectSP ptr = valobj.GetChildAtNamePath({"_M_dataplus", "_M_p"});
  if (!ptr || !ptr->GetError().Success())
    stream << "Summary Unavailable";
  else
    stream << ptr->GetSummaryAsCString();

  return true;
}

LibStdcppSharedPtrSyntheticFrontEnd::LibStdcppSharedPtrSyntheticFrontEnd(
    lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp) {
  if (valobj_sp)
    Update();
}

llvm::Expected<uint32_t>
LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() {
  return 1;
}

lldb::ValueObjectSP
LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(uint32_t idx) {
  if (!m_ptr_obj)
    return nullptr;

  if (idx == 0)
    return m_ptr_obj->GetSP();

  if (idx == 1) {
    ValueObjectSP valobj_sp = m_backend.GetSP();
    if (!valobj_sp)
      return nullptr;

    Status status;
    ValueObjectSP value_sp = m_ptr_obj->Dereference(status);
    if (status.Success())
      return value_sp;
  }
  return lldb::ValueObjectSP();
}

lldb::ChildCacheState LibStdcppSharedPtrSyntheticFrontEnd::Update() {
  auto backend = m_backend.GetSP();
  if (!backend)
    return lldb::ChildCacheState::eRefetch;

  auto valobj_sp = backend->GetNonSyntheticValue();
  if (!valobj_sp)
    return lldb::ChildCacheState::eRefetch;

  auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("_M_ptr");
  if (!ptr_obj_sp)
    return lldb::ChildCacheState::eRefetch;

  auto cast_ptr_sp = GetDesugaredSmartPointerValue(*ptr_obj_sp, *valobj_sp);
  if (!cast_ptr_sp)
    return lldb::ChildCacheState::eRefetch;

  m_ptr_obj = cast_ptr_sp->Clone(ConstString("pointer")).get();

  return lldb::ChildCacheState::eRefetch;
}

llvm::Expected<size_t>
LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(ConstString name) {
  if (name == "pointer")
    return 0;

  if (name == "object" || name == "$$dereference$$")
    return 1;

  return llvm::createStringError("Type has no child named '%s'",
                                 name.AsCString());
}

SyntheticChildrenFrontEnd *
lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  return (valobj_sp ? new LibStdcppSharedPtrSyntheticFrontEnd(valobj_sp)
                    : nullptr);
}

bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
  if (!valobj_sp)
    return false;

  ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("_M_ptr"));
  if (!ptr_sp)
    return false;

  DumpCxxSmartPtrPointerSummary(stream, *ptr_sp, options);

  ValueObjectSP pi_sp = valobj_sp->GetChildAtNamePath({"_M_refcount", "_M_pi"});
  if (!pi_sp)
    return false;

  bool success;
  uint64_t pi_addr = pi_sp->GetValueAsUnsigned(0, &success);
  // Empty control field. We're done.
  if (!success || pi_addr == 0)
    return true;

  int64_t shared_count = 0;
  if (auto count_sp = pi_sp->GetChildMemberWithName("_M_use_count")) {
    bool success;
    shared_count = count_sp->GetValueAsSigned(0, &success);
    if (!success)
      return false;

    stream.Printf(" strong=%" PRId64, shared_count);
  }

  // _M_weak_count is the number of weak references + (_M_use_count != 0).
  if (auto weak_count_sp = pi_sp->GetChildMemberWithName("_M_weak_count")) {
    bool success;
    int64_t count = weak_count_sp->GetValueAsUnsigned(0, &success);
    if (!success)
      return false;

    stream.Printf(" weak=%" PRId64, count - (shared_count != 0));
  }

  return true;
}

static uint64_t LibStdcppVariantNposValue(size_t index_byte_size) {
  switch (index_byte_size) {
  case 1:
    return 0xff;
  case 2:
    return 0xffff;
  default:
    return 0xffff'ffff;
  }
}

bool formatters::LibStdcppVariantSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  ValueObjectSP valobj_sp = valobj.GetNonSyntheticValue();
  if (!valobj_sp)
    return false;

  ValueObjectSP index_obj = valobj_sp->GetChildMemberWithName("_M_index");
  ValueObjectSP data_obj = valobj_sp->GetChildMemberWithName("_M_u");
  if (!index_obj || !data_obj)
    return false;

  auto index_bytes = index_obj->GetByteSize();
  if (!index_bytes)
    return false;
  auto npos_value = LibStdcppVariantNposValue(*index_bytes);
  auto index = index_obj->GetValueAsUnsigned(0);
  if (index == npos_value) {
    stream.Printf(" No Value");
    return true;
  }

  auto variant_type =
      valobj_sp->GetCompilerType().GetCanonicalType().GetNonReferenceType();
  if (!variant_type)
    return false;
  if (index >= variant_type.GetNumTemplateArguments(true)) {
    stream.Printf(" <Invalid>");
    return true;
  }

  auto active_type = variant_type.GetTypeTemplateArgument(index, true);
  stream << " Active Type = " << active_type.GetDisplayTypeName() << " ";
  return true;
}
