//===-- 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/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.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 <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);

  size_t CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;

  bool Update() override;

  bool MightHaveChildren() override;

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

  size_t CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;

  bool Update() override;

  bool MightHaveChildren() override;

  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)
  ValueObject* m_obj_obj = nullptr; // Underlying object (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();
}

bool LibstdcppMapIteratorSyntheticFrontEnd::Update() {
  ValueObjectSP valobj_sp = m_backend.GetSP();
  if (!valobj_sp)
    return false;

  TargetSP target_sp(valobj_sp->GetTargetSP());

  if (!target_sp)
    return false;

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

  if (!valobj_sp)
    return false;
  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();

  ValueObjectSP _M_node_sp(valobj_sp->GetChildMemberWithName("_M_node"));
  if (!_M_node_sp)
    return false;

  m_pair_address = _M_node_sp->GetValueAsUnsigned(0);
  if (m_pair_address == 0)
    return false;

  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 false;
    m_pair_type = pair_type;
  } else
    return false;

  return true;
}

size_t LibstdcppMapIteratorSyntheticFrontEnd::CalculateNumChildren() {
  return 2;
}

lldb::ValueObjectSP
LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex(size_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();
}

bool LibstdcppMapIteratorSyntheticFrontEnd::MightHaveChildren() { return true; }

size_t LibstdcppMapIteratorSyntheticFrontEnd::GetIndexOfChildWithName(
    ConstString name) {
  if (name == "first")
    return 0;
  if (name == "second")
    return 1;
  return UINT32_MAX;
}

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

bool VectorIteratorSyntheticFrontEnd::Update() {
  m_item_sp.reset();

  ValueObjectSP valobj_sp = m_backend.GetSP();
  if (!valobj_sp)
    return false;

  if (!valobj_sp)
    return false;

  ValueObjectSP item_ptr =
      formatters::GetChildMemberWithName(*valobj_sp, m_item_names);
  if (!item_ptr)
    return false;
  if (item_ptr->GetValueAsUnsigned(0) == 0)
    return false;
  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 false;
}

size_t VectorIteratorSyntheticFrontEnd::CalculateNumChildren() { return 1; }

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

bool VectorIteratorSyntheticFrontEnd::MightHaveChildren() { return true; }

size_t VectorIteratorSyntheticFrontEnd::GetIndexOfChildWithName(
    ConstString name) {
  if (name == "item")
    return 0;
  return UINT32_MAX;
}

bool lldb_private::formatters::LibStdcppStringSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  const bool scalar_is_load_addr = true;
  AddressType addr_type;
  lldb::addr_t addr_of_string = LLDB_INVALID_ADDRESS;
  if (valobj.IsPointerOrReferenceType()) {
    Status error;
    ValueObjectSP pointee_sp = valobj.Dereference(error);
    if (pointee_sp && error.Success())
      addr_of_string = pointee_sp->GetAddressOf(scalar_is_load_addr, &addr_type);
  } else
    addr_of_string =
        valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
  if (addr_of_string != LLDB_INVALID_ADDRESS) {
    switch (addr_type) {
    case eAddressTypeLoad: {
      ProcessSP process_sp(valobj.GetProcessSP());
      if (!process_sp)
        return false;

      StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
      Status error;
      lldb::addr_t addr_of_data =
          process_sp->ReadPointerFromMemory(addr_of_string, error);
      if (error.Fail() || addr_of_data == 0 ||
          addr_of_data == LLDB_INVALID_ADDRESS)
        return false;
      options.SetLocation(addr_of_data);
      options.SetTargetSP(valobj.GetTargetSP());
      options.SetStream(&stream);
      options.SetNeedsZeroTermination(false);
      options.SetBinaryZeroIsTerminator(true);
      lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(
          addr_of_string + process_sp->GetAddressByteSize(), error);
      if (error.Fail())
        return false;
      options.SetSourceSize(size_of_data);
      options.SetHasSourceSize(true);

      if (!StringPrinter::ReadStringAndDumpToStream<
              StringPrinter::StringElementType::UTF8>(options)) {
        stream.Printf("Summary Unavailable");
        return true;
      } else
        return true;
    } break;
    case eAddressTypeHost:
      break;
    case eAddressTypeInvalid:
    case eAddressTypeFile:
      break;
    }
  }
  return false;
}

bool lldb_private::formatters::LibStdcppWStringSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  const bool scalar_is_load_addr = true;
  AddressType addr_type;
  lldb::addr_t addr_of_string =
      valobj.GetAddressOf(scalar_is_load_addr, &addr_type);
  if (addr_of_string != LLDB_INVALID_ADDRESS) {
    switch (addr_type) {
    case eAddressTypeLoad: {
      ProcessSP process_sp(valobj.GetProcessSP());
      if (!process_sp)
        return false;

      CompilerType wchar_compiler_type =
          valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar);

      if (!wchar_compiler_type)
        return false;

      // Safe to pass nullptr for exe_scope here.
      std::optional<uint64_t> size = wchar_compiler_type.GetBitSize(nullptr);
      if (!size)
        return false;
      const uint32_t wchar_size = *size;

      StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
      Status error;
      lldb::addr_t addr_of_data =
          process_sp->ReadPointerFromMemory(addr_of_string, error);
      if (error.Fail() || addr_of_data == 0 ||
          addr_of_data == LLDB_INVALID_ADDRESS)
        return false;
      options.SetLocation(addr_of_data);
      options.SetTargetSP(valobj.GetTargetSP());
      options.SetStream(&stream);
      options.SetNeedsZeroTermination(false);
      options.SetBinaryZeroIsTerminator(false);
      lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory(
          addr_of_string + process_sp->GetAddressByteSize(), error);
      if (error.Fail())
        return false;
      options.SetSourceSize(size_of_data);
      options.SetHasSourceSize(true);
      options.SetPrefixToken("L");

      switch (wchar_size) {
      case 8:
        return StringPrinter::ReadStringAndDumpToStream<
            StringPrinter::StringElementType::UTF8>(options);
      case 16:
        return StringPrinter::ReadStringAndDumpToStream<
            StringPrinter::StringElementType::UTF16>(options);
      case 32:
        return StringPrinter::ReadStringAndDumpToStream<
            StringPrinter::StringElementType::UTF32>(options);
      default:
        stream.Printf("size for wchar_t is not valid");
        return true;
      }
      return true;
    } break;
    case eAddressTypeHost:
      break;
    case eAddressTypeInvalid:
    case eAddressTypeFile:
      break;
    }
  }
  return false;
}

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

size_t LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() { return 1; }

lldb::ValueObjectSP
LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
  if (idx == 0)
    return m_ptr_obj->GetSP();
  if (idx == 1) {
    if (m_ptr_obj && !m_obj_obj) {
      Status error;
      ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
      if (error.Success())
        m_obj_obj = obj_obj->Clone(ConstString("object")).get();
    }
    if (m_obj_obj)
      return m_obj_obj->GetSP();
  }
  return lldb::ValueObjectSP();
}

bool LibStdcppSharedPtrSyntheticFrontEnd::Update() {
  auto backend = m_backend.GetSP();
  if (!backend)
    return false;

  auto valobj_sp = backend->GetNonSyntheticValue();
  if (!valobj_sp)
    return false;

  auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("_M_ptr");
  if (!ptr_obj_sp)
    return false;

  m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get();
  m_obj_obj = nullptr;

  return false;
}

bool LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() { return true; }

size_t LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName(
    ConstString name) {
  if (name == "pointer")
    return 0;
  if (name == "object" || name == "$$dereference$$")
    return 1;
  return UINT32_MAX;
}

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;

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

  if (ptr_sp->GetValueAsUnsigned(0) == 0 ||
      usecount_sp->GetValueAsUnsigned(0) == 0) {
    stream.Printf("nullptr");
    return true;
  }

  Status error;
  ValueObjectSP pointee_sp = ptr_sp->Dereference(error);
  if (pointee_sp && error.Success()) {
    if (pointee_sp->DumpPrintableRepresentation(
            stream, ValueObject::eValueObjectRepresentationStyleSummary,
            lldb::eFormatInvalid,
            ValueObject::PrintableRepresentationSpecialCases::eDisable,
            false)) {
      return true;
    }
  }

  stream.Printf("ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned(0));
  return true;
}
