//===-- GenericList.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 "LibCxx.h"
#include "MsvcStl.h"

#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Status.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/ValueObject/ValueObjectConstResult.h"
#include "lldb/lldb-enumerations.h"

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

namespace {

enum class StlType {
  LibCxx,
  MsvcStl,
};

template <StlType Stl> class ListEntry {
public:
  ListEntry() = default;
  ListEntry(ValueObjectSP entry_sp) : m_entry_sp(std::move(entry_sp)) {}
  ListEntry(ValueObject *entry)
      : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {}

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

  ListEntry next();
  ListEntry prev();

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

  explicit operator bool() { return GetEntry() && !null(); }

  ValueObjectSP GetEntry() { return m_entry_sp; }

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

  bool operator==(const ListEntry &rhs) const { return value() == rhs.value(); }

  bool operator!=(const ListEntry &rhs) const { return !(*this == rhs); }

private:
  ValueObjectSP m_entry_sp;
};

template <> ListEntry<StlType::LibCxx> ListEntry<StlType::LibCxx>::next() {
  if (!m_entry_sp)
    return ListEntry();
  return ListEntry(m_entry_sp->GetChildMemberWithName("__next_"));
}

template <> ListEntry<StlType::LibCxx> ListEntry<StlType::LibCxx>::prev() {
  if (!m_entry_sp)
    return ListEntry();
  return ListEntry(m_entry_sp->GetChildMemberWithName("__prev_"));
}

template <> ListEntry<StlType::MsvcStl> ListEntry<StlType::MsvcStl>::next() {
  if (!m_entry_sp)
    return ListEntry();
  return ListEntry(m_entry_sp->GetChildMemberWithName("_Next"));
}

template <> ListEntry<StlType::MsvcStl> ListEntry<StlType::MsvcStl>::prev() {
  if (!m_entry_sp)
    return ListEntry();
  return ListEntry(m_entry_sp->GetChildMemberWithName("_Prev"));
}

template <StlType Stl> class ListIterator {
public:
  ListIterator() = default;
  ListIterator(ListEntry<Stl> entry) : m_entry(std::move(entry)) {}
  ListIterator(ValueObjectSP entry) : m_entry(std::move(entry)) {}
  ListIterator(ValueObject *entry) : m_entry(entry) {}

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

  ValueObjectSP advance(size_t count) {
    if (count == 0)
      return m_entry.GetEntry();
    if (count == 1) {
      next();
      return m_entry.GetEntry();
    }
    while (count > 0) {
      next();
      count--;
      if (m_entry.null())
        return lldb::ValueObjectSP();
    }
    return m_entry.GetEntry();
  }

  bool operator==(const ListIterator &rhs) const {
    return (rhs.m_entry == m_entry);
  }

protected:
  void next() { m_entry = m_entry.next(); }

  void prev() { m_entry = m_entry.prev(); }

private:
  ListEntry<Stl> m_entry;
};

template <StlType Stl>
class AbstractListFrontEnd : public SyntheticChildrenFrontEnd {
public:
  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override {
    auto optional_idx = formatters::ExtractIndexFromString(name.GetCString());
    if (!optional_idx) {
      return llvm::createStringError("Type has no child named '%s'",
                                     name.AsCString());
    }
    return *optional_idx;
  }
  lldb::ChildCacheState Update() override;

protected:
  AbstractListFrontEnd(ValueObject &valobj)
      : SyntheticChildrenFrontEnd(valobj) {}

  size_t m_count = 0;
  ValueObject *m_head = nullptr;

  static constexpr bool g_use_loop_detect = true;
  size_t m_loop_detected = 0;   // The number of elements that have had loop
                                // detection run over them.
  ListEntry<Stl> m_slow_runner; // Used for loop detection
  ListEntry<Stl> m_fast_runner; // Used for loop detection

  size_t m_list_capping_size = 0;
  CompilerType m_element_type;
  std::map<size_t, ListIterator<Stl>> m_iterators;

  bool HasLoop(size_t count);
  ValueObjectSP GetItem(size_t idx);
};

class LibCxxForwardListFrontEnd : public AbstractListFrontEnd<StlType::LibCxx> {
public:
  LibCxxForwardListFrontEnd(ValueObject &valobj);

  llvm::Expected<uint32_t> CalculateNumChildren() override;
  ValueObjectSP GetChildAtIndex(uint32_t idx) override;
  lldb::ChildCacheState Update() override;
};

class LibCxxListFrontEnd : public AbstractListFrontEnd<StlType::LibCxx> {
public:
  LibCxxListFrontEnd(lldb::ValueObjectSP valobj_sp);

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

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

private:
  lldb::addr_t m_node_address = 0;
  ValueObject *m_tail = nullptr;
};

class MsvcStlForwardListFrontEnd
    : public AbstractListFrontEnd<StlType::MsvcStl> {
public:
  MsvcStlForwardListFrontEnd(ValueObject &valobj);

  llvm::Expected<uint32_t> CalculateNumChildren() override;
  ValueObjectSP GetChildAtIndex(uint32_t idx) override;
  lldb::ChildCacheState Update() override;
};

class MsvcStlListFrontEnd : public AbstractListFrontEnd<StlType::MsvcStl> {
public:
  MsvcStlListFrontEnd(lldb::ValueObjectSP valobj_sp);

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

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

private:
  ValueObject *m_tail = nullptr;
};

/// Gets the (forward-)list element type from the head node instead of the
/// template arguments. This is needed with PDB as it doesn't have info about
/// the template arguments.
CompilerType GetMsvcStlElementTypeFromHead(ValueObject &head) {
  auto val_sp = head.GetChildMemberWithName("_Myval");
  if (val_sp)
    return val_sp->GetCompilerType();
  return CompilerType();
}

} // end anonymous namespace

template <StlType Stl>
lldb::ChildCacheState AbstractListFrontEnd<Stl>::Update() {
  m_loop_detected = 0;
  m_count = UINT32_MAX;
  m_head = nullptr;
  m_list_capping_size = 0;
  m_slow_runner.SetEntry(nullptr);
  m_fast_runner.SetEntry(nullptr);
  m_iterators.clear();

  if (m_backend.GetTargetSP())
    m_list_capping_size =
        m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
  if (m_list_capping_size == 0)
    m_list_capping_size = 255;

  CompilerType list_type = m_backend.GetCompilerType();
  if (list_type.IsReferenceType())
    list_type = list_type.GetNonReferenceType();

  if (list_type.GetNumTemplateArguments() == 0)
    return lldb::ChildCacheState::eRefetch;
  m_element_type = list_type.GetTypeTemplateArgument(0);

  return lldb::ChildCacheState::eRefetch;
}

template <StlType Stl> bool AbstractListFrontEnd<Stl>::HasLoop(size_t count) {
  if (!g_use_loop_detect)
    return false;
  // don't bother checking for a loop if we won't actually need to jump nodes
  if (m_count < 2)
    return false;

  if (m_loop_detected == 0) {
    // This is the first time we are being run (after the last update). Set up
    // the loop invariant for the first element.
    m_slow_runner = ListEntry<Stl>(m_head).next();
    m_fast_runner = m_slow_runner.next();
    m_loop_detected = 1;
  }

  // Loop invariant:
  // Loop detection has been run over the first m_loop_detected elements. If
  // m_slow_runner == m_fast_runner then the loop has been detected after
  // m_loop_detected elements.
  const size_t steps_to_run = std::min(count, m_count);
  while (m_loop_detected < steps_to_run && m_slow_runner && m_fast_runner &&
         m_slow_runner != m_fast_runner) {

    m_slow_runner = m_slow_runner.next();
    m_fast_runner = m_fast_runner.next().next();
    m_loop_detected++;
  }
  if (count <= m_loop_detected)
    return false; // No loop in the first m_loop_detected elements.
  if (!m_slow_runner || !m_fast_runner)
    return false; // Reached the end of the list. Definitely no loops.
  return m_slow_runner == m_fast_runner;
}

template <StlType Stl>
ValueObjectSP AbstractListFrontEnd<Stl>::GetItem(size_t idx) {
  size_t advance = idx;
  ListIterator<Stl> current(m_head);
  if (idx > 0) {
    auto cached_iterator = m_iterators.find(idx - 1);
    if (cached_iterator != m_iterators.end()) {
      current = cached_iterator->second;
      advance = 1;
    }
  }
  ValueObjectSP value_sp = current.advance(advance);
  m_iterators[idx] = current;
  return value_sp;
}

LibCxxForwardListFrontEnd::LibCxxForwardListFrontEnd(ValueObject &valobj)
    : AbstractListFrontEnd(valobj) {
  Update();
}

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

  ListEntry<StlType::LibCxx> current(m_head);
  m_count = 0;
  while (current && m_count < m_list_capping_size) {
    ++m_count;
    current = current.next();
  }
  return m_count;
}

ValueObjectSP LibCxxForwardListFrontEnd::GetChildAtIndex(uint32_t idx) {
  if (idx >= CalculateNumChildrenIgnoringErrors())
    return nullptr;

  if (!m_head)
    return nullptr;

  if (HasLoop(idx + 1))
    return nullptr;

  ValueObjectSP current_sp = GetItem(idx);
  if (!current_sp)
    return nullptr;

  current_sp = current_sp->GetChildAtIndex(1); // get the __value_ child
  if (!current_sp)
    return nullptr;

  // we need to copy current_sp into a new object otherwise we will end up with
  // all items named __value_
  DataExtractor data;
  Status error;
  current_sp->GetData(data, error);
  if (error.Fail())
    return nullptr;

  return CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), data,
                                   m_backend.GetExecutionContextRef(),
                                   m_element_type);
}

lldb::ChildCacheState LibCxxForwardListFrontEnd::Update() {
  AbstractListFrontEnd::Update();

  Status err;
  ValueObjectSP backend_addr(m_backend.AddressOf(err));
  if (err.Fail() || !backend_addr)
    return lldb::ChildCacheState::eRefetch;

  auto list_base_sp = m_backend.GetChildAtIndex(0);
  if (!list_base_sp)
    return lldb::ChildCacheState::eRefetch;

  // Anonymous strucutre index is in base class at index 0.
  auto [impl_sp, is_compressed_pair] = GetValueOrOldCompressedPair(
      *list_base_sp, "__before_begin_", "__before_begin_");
  if (!impl_sp)
    return ChildCacheState::eRefetch;

  if (is_compressed_pair)
    impl_sp = GetFirstValueOfLibCXXCompressedPair(*impl_sp);

  if (!impl_sp)
    return ChildCacheState::eRefetch;

  m_head = impl_sp->GetChildMemberWithName("__next_").get();

  return ChildCacheState::eRefetch;
}

LibCxxListFrontEnd::LibCxxListFrontEnd(lldb::ValueObjectSP valobj_sp)
    : AbstractListFrontEnd(*valobj_sp) {
  if (valobj_sp)
    Update();
}

llvm::Expected<uint32_t> LibCxxListFrontEnd::CalculateNumChildren() {
  if (m_count != UINT32_MAX)
    return m_count;
  if (!m_head || !m_tail || m_node_address == 0)
    return 0;

  auto [size_node_sp, is_compressed_pair] =
      GetValueOrOldCompressedPair(m_backend, "__size_", "__size_alloc_");
  if (is_compressed_pair)
    size_node_sp = GetFirstValueOfLibCXXCompressedPair(*size_node_sp);

  if (size_node_sp)
    m_count = size_node_sp->GetValueAsUnsigned(UINT32_MAX);

  if (m_count != UINT32_MAX)
    return m_count;

  uint64_t next_val = m_head->GetValueAsUnsigned(0);
  uint64_t prev_val = m_tail->GetValueAsUnsigned(0);
  if (next_val == 0 || prev_val == 0)
    return 0;
  if (next_val == m_node_address)
    return 0;
  if (next_val == prev_val)
    return 1;
  uint64_t size = 2;
  ListEntry<StlType::LibCxx> current(m_head);
  while (current.next() && current.next().value() != m_node_address) {
    size++;
    current = current.next();
    if (size > m_list_capping_size)
      break;
  }
  return m_count = (size - 1);
}

lldb::ValueObjectSP LibCxxListFrontEnd::GetChildAtIndex(uint32_t idx) {
  static ConstString g_value("__value_");
  static ConstString g_next("__next_");

  if (idx >= CalculateNumChildrenIgnoringErrors())
    return lldb::ValueObjectSP();

  if (!m_head || !m_tail || m_node_address == 0)
    return lldb::ValueObjectSP();

  if (HasLoop(idx + 1))
    return lldb::ValueObjectSP();

  ValueObjectSP current_sp = GetItem(idx);
  if (!current_sp)
    return lldb::ValueObjectSP();

  current_sp = current_sp->GetChildAtIndex(1); // get the __value_ child
  if (!current_sp)
    return lldb::ValueObjectSP();

  if (current_sp->GetName() == g_next) {
    ProcessSP process_sp(current_sp->GetProcessSP());
    if (!process_sp)
      return lldb::ValueObjectSP();

    // if we grabbed the __next_ pointer, then the child is one pointer deep-er
    lldb::addr_t addr = current_sp->GetParent()->GetPointerValue().address;
    addr = addr + 2 * process_sp->GetAddressByteSize();
    ExecutionContext exe_ctx(process_sp);
    current_sp =
        CreateValueObjectFromAddress("__value_", addr, exe_ctx, m_element_type);
    if (!current_sp)
      return lldb::ValueObjectSP();
  }

  // we need to copy current_sp into a new object otherwise we will end up with
  // all items named __value_
  DataExtractor data;
  Status error;
  current_sp->GetData(data, error);
  if (error.Fail())
    return lldb::ValueObjectSP();

  StreamString name;
  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
  return CreateValueObjectFromData(name.GetString(), data,
                                   m_backend.GetExecutionContextRef(),
                                   m_element_type);
}

lldb::ChildCacheState LibCxxListFrontEnd::Update() {
  AbstractListFrontEnd::Update();
  m_tail = nullptr;
  m_node_address = 0;

  Status err;
  ValueObjectSP backend_addr(m_backend.AddressOf(err));
  if (err.Fail() || !backend_addr)
    return lldb::ChildCacheState::eRefetch;
  m_node_address = backend_addr->GetValueAsUnsigned(0);
  if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS)
    return lldb::ChildCacheState::eRefetch;
  ValueObjectSP impl_sp(m_backend.GetChildMemberWithName("__end_"));
  if (!impl_sp)
    return lldb::ChildCacheState::eRefetch;
  m_head = impl_sp->GetChildMemberWithName("__next_").get();
  m_tail = impl_sp->GetChildMemberWithName("__prev_").get();
  return lldb::ChildCacheState::eRefetch;
}

MsvcStlForwardListFrontEnd::MsvcStlForwardListFrontEnd(ValueObject &valobj)
    : AbstractListFrontEnd(valobj) {
  Update();
}

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

  ListEntry<StlType::MsvcStl> current(m_head);
  m_count = 0;
  while (current && m_count < m_list_capping_size) {
    ++m_count;
    current = current.next();
  }
  return m_count;
}

ValueObjectSP MsvcStlForwardListFrontEnd::GetChildAtIndex(uint32_t idx) {
  if (idx >= CalculateNumChildrenIgnoringErrors())
    return nullptr;

  if (!m_head)
    return nullptr;

  if (HasLoop(idx + 1))
    return nullptr;

  ValueObjectSP current_sp = GetItem(idx);
  if (!current_sp)
    return nullptr;

  current_sp = current_sp->GetChildAtIndex(1); // get the _Myval child
  if (!current_sp)
    return nullptr;

  // we need to copy current_sp into a new object otherwise we will end up with
  // all items named _Myval
  DataExtractor data;
  Status error;
  current_sp->GetData(data, error);
  if (error.Fail())
    return nullptr;

  return CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), data,
                                   m_backend.GetExecutionContextRef(),
                                   m_element_type);
}

lldb::ChildCacheState MsvcStlForwardListFrontEnd::Update() {
  AbstractListFrontEnd::Update();

  if (auto head_sp =
          m_backend.GetChildAtNamePath({"_Mypair", "_Myval2", "_Myhead"}))
    m_head = head_sp.get();

  // With PDB, we can't get the element type from the template arguments
  if (!m_element_type && m_head)
    m_element_type = GetMsvcStlElementTypeFromHead(*m_head);

  return ChildCacheState::eRefetch;
}

MsvcStlListFrontEnd::MsvcStlListFrontEnd(lldb::ValueObjectSP valobj_sp)
    : AbstractListFrontEnd(*valobj_sp) {
  if (valobj_sp)
    Update();
}

llvm::Expected<uint32_t> MsvcStlListFrontEnd::CalculateNumChildren() {
  if (m_count != UINT32_MAX)
    return m_count;
  if (!m_head || !m_tail)
    return 0;

  auto size_sp =
      m_backend.GetChildAtNamePath({"_Mypair", "_Myval2", "_Mysize"});
  if (!size_sp)
    return llvm::createStringError("Failed to resolve size.");

  m_count = size_sp->GetValueAsUnsigned(UINT32_MAX);
  if (m_count == UINT32_MAX)
    return llvm::createStringError("Failed to read size value.");

  return m_count;
}

lldb::ValueObjectSP MsvcStlListFrontEnd::GetChildAtIndex(uint32_t idx) {
  if (idx >= CalculateNumChildrenIgnoringErrors())
    return lldb::ValueObjectSP();

  if (!m_head || !m_tail)
    return lldb::ValueObjectSP();

  if (HasLoop(idx + 1))
    return lldb::ValueObjectSP();

  ValueObjectSP current_sp = GetItem(idx);
  if (!current_sp)
    return lldb::ValueObjectSP();

  current_sp = current_sp->GetChildAtIndex(2); // get the _Myval child
  if (!current_sp)
    return lldb::ValueObjectSP();

  // we need to copy current_sp into a new object otherwise we will end up with
  // all items named _Myval
  DataExtractor data;
  Status error;
  current_sp->GetData(data, error);
  if (error.Fail())
    return lldb::ValueObjectSP();

  StreamString name;
  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
  return CreateValueObjectFromData(name.GetString(), data,
                                   m_backend.GetExecutionContextRef(),
                                   m_element_type);
}

lldb::ChildCacheState MsvcStlListFrontEnd::Update() {
  AbstractListFrontEnd::Update();
  m_tail = nullptr;
  m_head = nullptr;

  ValueObjectSP last =
      m_backend.GetChildAtNamePath({"_Mypair", "_Myval2", "_Myhead"});
  if (!last)
    return lldb::ChildCacheState::eRefetch;
  ValueObjectSP first = last->GetChildMemberWithName("_Next");
  if (!first)
    return lldb::ChildCacheState::eRefetch;

  m_head = first.get();
  m_tail = last.get();

  // With PDB, we can't get the element type from the template arguments
  if (!m_element_type && m_head)
    m_element_type = GetMsvcStlElementTypeFromHead(*m_head);

  return lldb::ChildCacheState::eRefetch;
}

SyntheticChildrenFrontEnd *formatters::LibcxxStdListSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  return (valobj_sp ? new LibCxxListFrontEnd(valobj_sp) : nullptr);
}

SyntheticChildrenFrontEnd *
formatters::LibcxxStdForwardListSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  return valobj_sp ? new LibCxxForwardListFrontEnd(*valobj_sp) : nullptr;
}

bool formatters::IsMsvcStlList(ValueObject &valobj) {
  if (auto valobj_sp = valobj.GetNonSyntheticValue())
    return valobj_sp->GetChildMemberWithName("_Mypair") != nullptr;

  return false;
}

SyntheticChildrenFrontEnd *
formatters::MsvcStlListSyntheticFrontEndCreator(CXXSyntheticChildren *,
                                                lldb::ValueObjectSP valobj_sp) {
  return (valobj_sp ? new MsvcStlListFrontEnd(valobj_sp) : nullptr);
}

SyntheticChildrenFrontEnd *
formatters::MsvcStlForwardListSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  return valobj_sp ? new MsvcStlForwardListFrontEnd(*valobj_sp) : nullptr;
}
