//===-- 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 "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/LLDBLog.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 = CreateChildValueObjectFromAddress("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 = CreateChildValueObjectFromAddress(
      "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("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_or_err = index_obj->GetByteSize();
  if (!index_bytes_or_err) {
    LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters),
                   index_bytes_or_err.takeError(),
                   "failed to get variant index byte size: {0}");
    return false;
  }
  auto npos_value = LibStdcppVariantNposValue(*index_bytes_or_err);
  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;
}

bool lldb_private::formatters::LibStdcppSourceLocationSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  ValueObjectSP impl_sp = valobj.GetChildMemberWithName("_M_impl");
  if (!impl_sp)
    return false;

  ValueObjectSP file_sp = impl_sp->GetChildMemberWithName("_M_file_name");
  ValueObjectSP function_sp =
      impl_sp->GetChildMemberWithName("_M_function_name");
  ValueObjectSP line_sp = impl_sp->GetChildMemberWithName("_M_line");
  ValueObjectSP column_sp = impl_sp->GetChildMemberWithName("_M_column");

  if (!file_sp || !function_sp || !line_sp || !column_sp)
    return false;

  bool success = false;
  uint64_t line = line_sp->GetValueAsUnsigned(0, &success);
  if (!success)
    return false;

  uint64_t column = column_sp->GetValueAsUnsigned(0, &success);
  if (!success)
    return false;

  const char *file = file_sp->GetSummaryAsCString();
  stream.Format("{0}:{1}:{2}", file ? file : "<unknown>", line, column);

  if (const char *function = function_sp->GetSummaryAsCString())
    stream.Printf(" (%s)", function);

  return true;
}
