//===-- 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/CxxStringTypes.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 "llvm/Support/ErrorExtras.h"
#include <optional>

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

namespace {

using StringElementType = StringPrinter::StringElementType;

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::createStringErrorV("type has no child named '{0}'", name);
}

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::createStringErrorV("type has no child named '{0}'", name);
}

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;
}

template <StringPrinter::StringElementType element_type>
static bool formatStringViewImpl(ValueObject &valobj, Stream &stream,
                                 const TypeSummaryOptions &summary_options,
                                 std::string prefix_token) {
  auto data_sp = valobj.GetChildMemberWithName("_M_str");
  auto size_sp = valobj.GetChildMemberWithName("_M_len");
  if (!data_sp || !size_sp)
    return false;

  bool success = false;
  uint64_t size = size_sp->GetValueAsUnsigned(0, &success);
  if (!success) {
    stream << "Summary Unavailable";
    return true;
  }

  StreamString scratch_stream;
  success = StringBufferSummaryProvider<element_type>(
      scratch_stream, summary_options, data_sp, size, prefix_token);

  if (success)
    stream << scratch_stream.GetData();
  else
    stream << "Summary Unavailable";
  return true;
}

bool lldb_private::formatters::LibStdcppWStringViewSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  auto wchar_t_size = GetWCharByteSize(valobj);
  if (!wchar_t_size)
    return false;

  switch (*wchar_t_size) {
  case 1:
    return formatStringViewImpl<StringElementType::UTF8>(valobj, stream,
                                                         options, "L");
  case 2:
    return formatStringViewImpl<StringElementType::UTF16>(valobj, stream,
                                                          options, "L");
  case 4:
    return formatStringViewImpl<StringElementType::UTF32>(valobj, stream,
                                                          options, "L");
  }
  return false;
}

template <StringElementType element_type>
static constexpr const char *getPrefixToken() {
  switch (element_type) {
  case StringElementType::ASCII:
    return "";
  case StringElementType::UTF8:
    return "u8";
  case StringElementType::UTF16:
    return "u";
  case StringElementType::UTF32:
    return "U";
  }
  llvm_unreachable("invalid element type");
}

template <StringPrinter::StringElementType element_type>
bool lldb_private::formatters::LibStdcppStringViewSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  return formatStringViewImpl<element_type>(valobj, stream, options,
                                            getPrefixToken<element_type>());
}

template bool lldb_private::formatters::LibStdcppStringViewSummaryProvider<
    StringElementType::ASCII>(ValueObject &, Stream &,
                              const TypeSummaryOptions &);
template bool lldb_private::formatters::LibStdcppStringViewSummaryProvider<
    StringElementType::UTF8>(ValueObject &, Stream &,
                             const TypeSummaryOptions &);
template bool lldb_private::formatters::LibStdcppStringViewSummaryProvider<
    StringElementType::UTF16>(ValueObject &, Stream &,
                              const TypeSummaryOptions &);
template bool lldb_private::formatters::LibStdcppStringViewSummaryProvider<
    StringElementType::UTF32>(ValueObject &, Stream &,
                              const TypeSummaryOptions &);

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::createStringErrorV("type has no child named '{0}'", name);
}

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;
}

static std::optional<int64_t>
LibStdcppExtractOrderingValue(ValueObject &valobj) {
  lldb::ValueObjectSP value_sp = valobj.GetChildMemberWithName("_M_value");
  if (!value_sp)
    return std::nullopt;
  bool success;
  int64_t value = value_sp->GetValueAsSigned(0, &success);
  if (!success)
    return std::nullopt;
  return value;
}

bool lldb_private::formatters::LibStdcppPartialOrderingSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  std::optional<int64_t> value = LibStdcppExtractOrderingValue(valobj);
  if (!value)
    return false;
  switch (*value) {
  case -1:
    stream << "less";
    break;
  case 0:
    stream << "equivalent";
    break;
  case 1:
    stream << "greater";
    break;
  case -128:
  case 2:
    stream << "unordered";
    break;
  default:
    return false;
  }
  return true;
}

bool lldb_private::formatters::LibStdcppWeakOrderingSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  std::optional<int64_t> value = LibStdcppExtractOrderingValue(valobj);
  if (!value)
    return false;
  switch (*value) {
  case -1:
    stream << "less";
    break;
  case 0:
    stream << "equivalent";
    break;
  case 1:
    stream << "greater";
    break;
  default:
    return false;
  }
  return true;
}

bool lldb_private::formatters::LibStdcppStrongOrderingSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  std::optional<int64_t> value = LibStdcppExtractOrderingValue(valobj);
  if (!value)
    return false;
  switch (*value) {
  case -1:
    stream << "less";
    break;
  case 0:
    stream << "equal";
    break;
  case 1:
    stream << "greater";
    break;
  default:
    return false;
  }
  return true;
}
