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