//===-- MsvcStlTree.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 "MsvcStl.h"

#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include <cstdint>
#include <optional>

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

// A Node looks as follows:
// struct _Tree_node {
//   _Tree_node *_Left;
//   _Tree_node *_Parent;
//   _Tree_node *_Right;
//   char _Color;
//   char _Isnil;         // true (!= 0) if head or nil node
//   value_type _Myval;
// };

namespace {

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

  ValueObjectSP left() const {
    if (!m_entry_sp)
      return m_entry_sp;
    return m_entry_sp->GetSyntheticChildAtOffset(
        0, m_entry_sp->GetCompilerType(), true);
  }

  ValueObjectSP right() const {
    if (!m_entry_sp)
      return m_entry_sp;
    return m_entry_sp->GetSyntheticChildAtOffset(
        2 * m_entry_sp->GetProcessSP()->GetAddressByteSize(),
        m_entry_sp->GetCompilerType(), true);
  }

  ValueObjectSP parent() const {
    if (!m_entry_sp)
      return m_entry_sp;
    return m_entry_sp->GetSyntheticChildAtOffset(
        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 is_nil() const {
    if (!m_entry_sp)
      return true;
    auto isnil_sp = m_entry_sp->GetChildMemberWithName("_Isnil");
    if (!isnil_sp)
      return true;
    return isnil_sp->GetValueAsUnsigned(1) != 0;
  }

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

  bool is_nullptr() 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(ValueObject *entry, size_t depth = 0)
      : m_entry(entry), m_max_depth(depth) {}

  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.is_nullptr() || (steps > m_max_depth))
        return fail;
    }
    return m_entry.GetEntry();
  }

private:
  /// Mimicks _Tree_unchecked_const_iterator::operator++()
  void next() {
    if (m_entry.is_nullptr())
      return;
    MapEntry right(m_entry.right());
    if (!right.is_nil()) {
      m_entry = tree_min(std::move(right));
      return;
    }
    size_t steps = 0;
    MapEntry pnode(m_entry.parent());
    while (!pnode.is_nil() &&
           m_entry.value() == MapEntry(pnode.right()).value()) {
      m_entry = pnode;
      steps++;
      if (steps > m_max_depth) {
        m_entry = MapEntry();
        return;
      }
      pnode.SetEntry(m_entry.parent());
    }
    m_entry = std::move(pnode);
  }

  /// Mimicks MSVC STL's _Min() algorithm (finding the leftmost node in the
  /// subtree).
  MapEntry tree_min(MapEntry pnode) {
    if (pnode.is_nullptr())
      return MapEntry();
    MapEntry left(pnode.left());
    size_t steps = 0;
    while (!left.is_nil()) {
      if (left.error()) {
        m_error = true;
        return MapEntry();
      }
      pnode = left;
      left.SetEntry(pnode.left());
      steps++;
      if (steps > m_max_depth)
        return MapEntry();
    }
    return pnode;
  }

  MapEntry m_entry;
  size_t m_max_depth = 0;
  bool m_error = false;
};

} // namespace

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

  ~MsvcStlTreeSyntheticFrontEnd() override = default;

  llvm::Expected<uint32_t> CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

private:
  /// Returns the ValueObject for the _Tree_node at index \ref idx.
  ///
  /// \param[in] idx The child index that we're looking to get the value for.
  ///
  /// \param[in] max_depth The maximum search depth after which we stop trying
  ///                      to find the node for.
  ///
  /// \returns On success, returns the ValueObjectSP corresponding to the
  ///          _Tree_node's _Myval member.
  ///          On failure, nullptr is returned.
  ValueObjectSP GetValueAt(size_t idx, size_t max_depth);

  ValueObject *m_tree = nullptr;
  ValueObject *m_begin_node = nullptr;
  size_t m_count = UINT32_MAX;
  std::map<size_t, MapIterator> m_iterators;
};

class MsvcStlTreeIterSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  MsvcStlTreeIterSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
      : SyntheticChildrenFrontEnd(*valobj_sp) {}

  llvm::Expected<uint32_t> CalculateNumChildren() override {
    if (!m_inner_sp)
      return 0;
    return m_inner_sp->GetNumChildren();
  }

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override {
    if (!m_inner_sp)
      return nullptr;
    return m_inner_sp->GetChildAtIndex(idx);
  }

  lldb::ChildCacheState Update() override;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override {
    if (!m_inner_sp)
      return llvm::createStringError("there are no children");
    return m_inner_sp->GetIndexOfChildWithName(name);
  }

  lldb::ValueObjectSP GetSyntheticValue() override { return m_inner_sp; }

private:
  ValueObjectSP m_inner_sp;
};

} // namespace formatters
} // namespace lldb_private

lldb_private::formatters::MsvcStlTreeSyntheticFrontEnd::
    MsvcStlTreeSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp) {
  if (valobj_sp)
    Update();
}

llvm::Expected<uint32_t>
lldb_private::formatters::MsvcStlTreeSyntheticFrontEnd::CalculateNumChildren() {
  if (m_count != UINT32_MAX)
    return m_count;

  if (m_tree == nullptr)
    return 0;

  if (auto node_sp = m_tree->GetChildMemberWithName("_Mysize")) {
    m_count = node_sp->GetValueAsUnsigned(0);
    return m_count;
  }

  return llvm::createStringError("failed to read size");
}

ValueObjectSP
lldb_private::formatters::MsvcStlTreeSyntheticFrontEnd::GetValueAt(
    size_t idx, size_t max_depth) {
  MapIterator iterator(m_begin_node, max_depth);

  size_t advance_by = idx;
  if (idx > 0) {
    // If we have already created the iterator for the previous
    // index, we can start from there and advance by 1.
    auto cached_iterator = m_iterators.find(idx - 1);
    if (cached_iterator != m_iterators.end()) {
      iterator = cached_iterator->second;
      advance_by = 1;
    }
  }

  ValueObjectSP iterated_sp(iterator.advance(advance_by));
  if (!iterated_sp)
    // this tree is garbage - stop
    return nullptr;

  ValueObjectSP value_sp = iterated_sp->GetChildMemberWithName("_Myval");
  if (!value_sp)
    return nullptr;

  m_iterators[idx] = iterator;

  return value_sp;
}

lldb::ValueObjectSP
lldb_private::formatters::MsvcStlTreeSyntheticFrontEnd::GetChildAtIndex(
    uint32_t idx) {
  uint32_t num_children = CalculateNumChildrenIgnoringErrors();
  if (idx >= num_children)
    return nullptr;

  if (m_tree == nullptr || m_begin_node == nullptr)
    return nullptr;

  ValueObjectSP val_sp = GetValueAt(idx, /*max_depth=*/num_children);
  if (!val_sp) {
    // this will stop all future searches until an Update() happens
    m_tree = nullptr;
    return nullptr;
  }

  // at this point we have a valid pair
  // we need to copy current_sp into a new object otherwise we will end up with
  // all items named _Myval
  StreamString name;
  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
  return val_sp->Clone(name.GetString());
}

lldb::ChildCacheState
lldb_private::formatters::MsvcStlTreeSyntheticFrontEnd::Update() {
  m_count = UINT32_MAX;
  m_tree = m_begin_node = nullptr;
  m_iterators.clear();
  m_tree =
      m_backend.GetChildAtNamePath({"_Mypair", "_Myval2", "_Myval2"}).get();
  if (!m_tree)
    return lldb::ChildCacheState::eRefetch;

  m_begin_node = m_tree->GetChildAtNamePath({"_Myhead", "_Left"}).get();

  return lldb::ChildCacheState::eRefetch;
}

lldb::ChildCacheState MsvcStlTreeIterSyntheticFrontEnd::Update() {
  m_inner_sp = nullptr;
  ValueObjectSP node_sp = m_backend.GetChildMemberWithName("_Ptr");
  if (!node_sp)
    return lldb::eRefetch;

  MapEntry entry(node_sp.get());
  if (entry.is_nil())
    return lldb::eRefetch; // end

  m_inner_sp = node_sp->GetChildMemberWithName("_Myval");
  return lldb::eRefetch;
}

bool formatters::IsMsvcStlTreeIter(ValueObject &valobj) {
  return valobj.GetChildMemberWithName("_Ptr") != nullptr;
}

bool formatters::MsvcStlTreeIterSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  auto valobj_sp = valobj.GetNonSyntheticValue();
  if (!valobj_sp)
    return false;
  auto node_sp = valobj_sp->GetChildMemberWithName("_Ptr");
  if (!node_sp)
    return false;

  MapEntry entry(node_sp.get());
  if (entry.is_nil()) {
    stream.Printf("end");
    return true;
  }

  auto value_sp = node_sp->GetChildMemberWithName("_Myval");
  if (!value_sp)
    return false;

  auto *summary = value_sp->GetSummaryAsCString();
  if (summary)
    stream << summary;
  return true;
}

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

bool formatters::IsMsvcStlMapLike(ValueObject &valobj) {
  return valobj.GetChildMemberWithName("_Mypair") != nullptr;
}

SyntheticChildrenFrontEnd *
lldb_private::formatters::MsvcStlMapLikeSyntheticFrontEndCreator(
    lldb::ValueObjectSP valobj_sp) {
  return (valobj_sp ? new MsvcStlTreeSyntheticFrontEnd(valobj_sp) : nullptr);
}
