//===-- 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/Language/CPlusPlus/VectorIterator.h"

#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/DataFormatters/StringPrinter.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(llvm::StringRef 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(llvm::StringRef 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(
    llvm::StringRef 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);
}

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(
    llvm::StringRef 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;
}
