//===-- LibCxxMap.cpp -------------------------------------------*- C++ -*-===//
//
// 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 "LibCxx.h"

#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Symbol/ClangASTContext.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"

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

class MapEntry {
public:
  MapEntry() = default;
  explicit MapEntry(ValueObjectSP entry_sp) : m_entry_sp(entry_sp) {}
  MapEntry(const MapEntry &rhs) = default;
  explicit MapEntry(ValueObject *entry)
      : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}

  ValueObjectSP left() const {
    static ConstString g_left("__left_");
    if (!m_entry_sp)
      return m_entry_sp;
    return m_entry_sp->GetSyntheticChildAtOffset(
        0, m_entry_sp->GetCompilerType(), true);
  }

  ValueObjectSP right() const {
    static ConstString g_right("__right_");
    if (!m_entry_sp)
      return m_entry_sp;
    return m_entry_sp->GetSyntheticChildAtOffset(
        m_entry_sp->GetProcessSP()->GetAddressByteSize(),
        m_entry_sp->GetCompilerType(), true);
  }

  ValueObjectSP parent() const {
    static ConstString g_parent("__parent_");
    if (!m_entry_sp)
      return m_entry_sp;
    return m_entry_sp->GetSyntheticChildAtOffset(
        2 * m_entry_sp->GetProcessSP()->GetAddressByteSize(),
        m_entry_sp->GetCompilerType(), true);
  }

  uint64_t value() const {
    if (!m_entry_sp)
      return 0;
    return m_entry_sp->GetValueAsUnsigned(0);
  }

  bool error() const {
    if (!m_entry_sp)
      return true;
    return m_entry_sp->GetError().Fail();
  }

  bool null() const { return (value() == 0); }

  ValueObjectSP GetEntry() const { return m_entry_sp; }

  void SetEntry(ValueObjectSP entry) { m_entry_sp = entry; }

  bool operator==(const MapEntry &rhs) const {
    return (rhs.m_entry_sp.get() == m_entry_sp.get());
  }

private:
  ValueObjectSP m_entry_sp;
};

class MapIterator {
public:
  MapIterator() = default;
  MapIterator(MapEntry entry, size_t depth = 0)
      : m_entry(entry), m_max_depth(depth), m_error(false) {}
  MapIterator(ValueObjectSP entry, size_t depth = 0)
      : m_entry(entry), m_max_depth(depth), m_error(false) {}
  MapIterator(const MapIterator &rhs)
      : m_entry(rhs.m_entry), m_max_depth(rhs.m_max_depth), m_error(false) {}
  MapIterator(ValueObject *entry, size_t depth = 0)
      : m_entry(entry), m_max_depth(depth), m_error(false) {}

  MapIterator &operator=(const MapIterator &) = default;

  ValueObjectSP value() { return m_entry.GetEntry(); }

  ValueObjectSP advance(size_t count) {
    ValueObjectSP fail;
    if (m_error)
      return fail;
    size_t steps = 0;
    while (count > 0) {
      next();
      count--, steps++;
      if (m_error || m_entry.null() || (steps > m_max_depth))
        return fail;
    }
    return m_entry.GetEntry();
  }

protected:
  void next() {
    if (m_entry.null())
      return;
    MapEntry right(m_entry.right());
    if (!right.null()) {
      m_entry = tree_min(std::move(right));
      return;
    }
    size_t steps = 0;
    while (!is_left_child(m_entry)) {
      if (m_entry.error()) {
        m_error = true;
        return;
      }
      m_entry.SetEntry(m_entry.parent());
      steps++;
      if (steps > m_max_depth) {
        m_entry = MapEntry();
        return;
      }
    }
    m_entry = MapEntry(m_entry.parent());
  }

private:
  MapEntry tree_min(MapEntry &&x) {
    if (x.null())
      return MapEntry();
    MapEntry left(x.left());
    size_t steps = 0;
    while (!left.null()) {
      if (left.error()) {
        m_error = true;
        return MapEntry();
      }
      x = left;
      left.SetEntry(x.left());
      steps++;
      if (steps > m_max_depth)
        return MapEntry();
    }
    return x;
  }

  bool is_left_child(const MapEntry &x) {
    if (x.null())
      return false;
    MapEntry rhs(x.parent());
    rhs.SetEntry(rhs.left());
    return x.value() == rhs.value();
  }

  MapEntry m_entry;
  size_t m_max_depth;
  bool m_error;
};

namespace lldb_private {
namespace formatters {
class LibcxxStdMapSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  LibcxxStdMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

  ~LibcxxStdMapSyntheticFrontEnd() override = default;

  size_t CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;

  bool Update() override;

  bool MightHaveChildren() override;

  size_t GetIndexOfChildWithName(ConstString name) override;

private:
  bool GetDataType();

  void GetValueOffset(const lldb::ValueObjectSP &node);

  ValueObject *m_tree;
  ValueObject *m_root_node;
  CompilerType m_element_type;
  uint32_t m_skip_size;
  size_t m_count;
  std::map<size_t, MapIterator> m_iterators;
};
} // namespace formatters
} // namespace lldb_private

lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
    LibcxxStdMapSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp), m_tree(nullptr),
      m_root_node(nullptr), m_element_type(), m_skip_size(UINT32_MAX),
      m_count(UINT32_MAX), m_iterators() {
  if (valobj_sp)
    Update();
}

size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
    CalculateNumChildren() {
  static ConstString g___pair3_("__pair3_");
  static ConstString g___first_("__first_");
  static ConstString g___value_("__value_");

  if (m_count != UINT32_MAX)
    return m_count;
  if (m_tree == nullptr)
    return 0;
  ValueObjectSP m_item(m_tree->GetChildMemberWithName(g___pair3_, true));
  if (!m_item)
    return 0;

  switch (m_item->GetCompilerType().GetNumDirectBaseClasses()) {
  case 1:
    // Assume a pre llvm r300140 __compressed_pair implementation:
    m_item = m_item->GetChildMemberWithName(g___first_, true);
    break;
  case 2: {
    // Assume a post llvm r300140 __compressed_pair implementation:
    ValueObjectSP first_elem_parent = m_item->GetChildAtIndex(0, true);
    m_item = first_elem_parent->GetChildMemberWithName(g___value_, true);
    break;
  }
  default:
    return false;
  }

  if (!m_item)
    return 0;
  m_count = m_item->GetValueAsUnsigned(0);
  return m_count;
}

bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {
  static ConstString g___value_("__value_");
  static ConstString g_tree_("__tree_");
  static ConstString g_pair3("__pair3_");

  if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem())
    return true;
  m_element_type.Clear();
  ValueObjectSP deref;
  Status error;
  deref = m_root_node->Dereference(error);
  if (!deref || error.Fail())
    return false;
  deref = deref->GetChildMemberWithName(g___value_, true);
  if (deref) {
    m_element_type = deref->GetCompilerType();
    return true;
  }
  deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3});
  if (!deref)
    return false;
  m_element_type = deref->GetCompilerType()
                       .GetTypeTemplateArgument(1)
                       .GetTypeTemplateArgument(1);
  if (m_element_type) {
    std::string name;
    uint64_t bit_offset_ptr;
    uint32_t bitfield_bit_size_ptr;
    bool is_bitfield_ptr;
    m_element_type = m_element_type.GetFieldAtIndex(
        0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
    m_element_type = m_element_type.GetTypedefedType();
    return m_element_type.IsValid();
  } else {
    m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0);
    return m_element_type.IsValid();
  }
}

void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset(
    const lldb::ValueObjectSP &node) {
  if (m_skip_size != UINT32_MAX)
    return;
  if (!node)
    return;
  CompilerType node_type(node->GetCompilerType());
  uint64_t bit_offset;
  if (node_type.GetIndexOfFieldWithName("__value_", nullptr, &bit_offset) !=
      UINT32_MAX) {
    m_skip_size = bit_offset / 8u;
  } else {
    ClangASTContext *ast_ctx =
        llvm::dyn_cast_or_null<ClangASTContext>(node_type.GetTypeSystem());
    if (!ast_ctx)
      return;
    CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
        ConstString(),
        {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
         {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
         {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
         {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)},
         {"payload", (m_element_type.GetCompleteType(), m_element_type)}});
    std::string child_name;
    uint32_t child_byte_size;
    int32_t child_byte_offset = 0;
    uint32_t child_bitfield_bit_size;
    uint32_t child_bitfield_bit_offset;
    bool child_is_base_class;
    bool child_is_deref_of_parent;
    uint64_t language_flags;
    if (tree_node_type
            .GetChildCompilerTypeAtIndex(
                nullptr, 4, true, true, true, child_name, child_byte_size,
                child_byte_offset, child_bitfield_bit_size,
                child_bitfield_bit_offset, child_is_base_class,
                child_is_deref_of_parent, nullptr, language_flags)
            .IsValid())
      m_skip_size = (uint32_t)child_byte_offset;
  }
}

lldb::ValueObjectSP
lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
    size_t idx) {
  static ConstString g___cc("__cc");
  static ConstString g___nc("__nc");
  static ConstString g___value_("__value_");

  if (idx >= CalculateNumChildren())
    return lldb::ValueObjectSP();
  if (m_tree == nullptr || m_root_node == nullptr)
    return lldb::ValueObjectSP();

  MapIterator iterator(m_root_node, CalculateNumChildren());

  const bool need_to_skip = (idx > 0);
  size_t actual_advancde = idx;
  if (need_to_skip) {
    auto cached_iterator = m_iterators.find(idx - 1);
    if (cached_iterator != m_iterators.end()) {
      iterator = cached_iterator->second;
      actual_advancde = 1;
    }
  }

  ValueObjectSP iterated_sp(iterator.advance(actual_advancde));
  if (!iterated_sp) {
    // this tree is garbage - stop
    m_tree =
        nullptr; // this will stop all future searches until an Update() happens
    return iterated_sp;
  }
  if (GetDataType()) {
    if (!need_to_skip) {
      Status error;
      iterated_sp = iterated_sp->Dereference(error);
      if (!iterated_sp || error.Fail()) {
        m_tree = nullptr;
        return lldb::ValueObjectSP();
      }
      GetValueOffset(iterated_sp);
      auto child_sp = iterated_sp->GetChildMemberWithName(g___value_, true);
      if (child_sp)
        iterated_sp = child_sp;
      else
        iterated_sp = iterated_sp->GetSyntheticChildAtOffset(
            m_skip_size, m_element_type, true);
      if (!iterated_sp) {
        m_tree = nullptr;
        return lldb::ValueObjectSP();
      }
    } else {
      // because of the way our debug info is made, we need to read item 0
      // first so that we can cache information used to generate other elements
      if (m_skip_size == UINT32_MAX)
        GetChildAtIndex(0);
      if (m_skip_size == UINT32_MAX) {
        m_tree = nullptr;
        return lldb::ValueObjectSP();
      }
      iterated_sp = iterated_sp->GetSyntheticChildAtOffset(
          m_skip_size, m_element_type, true);
      if (!iterated_sp) {
        m_tree = nullptr;
        return lldb::ValueObjectSP();
      }
    }
  } else {
    m_tree = nullptr;
    return lldb::ValueObjectSP();
  }
  // at this point we have a valid
  // we need to copy current_sp into a new object otherwise we will end up with
  // all items named __value_
  DataExtractor data;
  Status error;
  iterated_sp->GetData(data, error);
  if (error.Fail()) {
    m_tree = nullptr;
    return lldb::ValueObjectSP();
  }
  StreamString name;
  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
  auto potential_child_sp = CreateValueObjectFromData(
      name.GetString(), data, m_backend.GetExecutionContextRef(),
      m_element_type);
  if (potential_child_sp) {
    switch (potential_child_sp->GetNumChildren()) {
    case 1: {
      auto child0_sp = potential_child_sp->GetChildAtIndex(0, true);
      if (child0_sp && child0_sp->GetName() == g___cc)
        potential_child_sp = child0_sp->Clone(ConstString(name.GetString()));
      break;
    }
    case 2: {
      auto child0_sp = potential_child_sp->GetChildAtIndex(0, true);
      auto child1_sp = potential_child_sp->GetChildAtIndex(1, true);
      if (child0_sp && child0_sp->GetName() == g___cc && child1_sp &&
          child1_sp->GetName() == g___nc)
        potential_child_sp = child0_sp->Clone(ConstString(name.GetString()));
      break;
    }
    }
  }
  m_iterators[idx] = iterator;
  return potential_child_sp;
}

bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update() {
  static ConstString g___tree_("__tree_");
  static ConstString g___begin_node_("__begin_node_");
  m_count = UINT32_MAX;
  m_tree = m_root_node = nullptr;
  m_iterators.clear();
  m_tree = m_backend.GetChildMemberWithName(g___tree_, true).get();
  if (!m_tree)
    return false;
  m_root_node = m_tree->GetChildMemberWithName(g___begin_node_, true).get();
  return false;
}

bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
    MightHaveChildren() {
  return true;
}

size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
    GetIndexOfChildWithName(ConstString name) {
  return ExtractIndexFromString(name.GetCString());
}

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