//===-- LibCxxList.cpp ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "LibCxx.h"

#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/Target.h"

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

namespace {

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

  ListEntry next() {
    static ConstString g_next("__next_");

    if (!m_entry_sp)
      return ListEntry();
    return ListEntry(m_entry_sp->GetChildMemberWithName(g_next, true));
  }

  ListEntry prev() {
    static ConstString g_prev("__prev_");

    if (!m_entry_sp)
      return ListEntry();
    return ListEntry(m_entry_sp->GetChildMemberWithName(g_prev, true));
  }

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

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

class ListIterator {
public:
  ListIterator() = default;
  ListIterator(ListEntry entry) : m_entry(entry) {}
  ListIterator(ValueObjectSP entry) : m_entry(entry) {}
  ListIterator(const ListIterator &rhs) = default;
  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 m_entry;
};

} // end anonymous namespace

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

  ~LibcxxStdListSyntheticFrontEnd() override = default;

  size_t CalculateNumChildren() override;

  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;

  bool Update() override;

  bool MightHaveChildren() override;

  size_t GetIndexOfChildWithName(const ConstString &name) override;

private:
  bool HasLoop(size_t count);

  size_t m_list_capping_size;
  static const bool g_use_loop_detect = true;

  size_t m_loop_detected; // The number of elements that have had loop detection
                          // run over them.
  ListEntry m_slow_runner; // Used for loop detection
  ListEntry m_fast_runner; // Used for loop detection

  lldb::addr_t m_node_address;
  ValueObject *m_head;
  ValueObject *m_tail;
  CompilerType m_element_type;
  size_t m_count;
  std::map<size_t, ListIterator> m_iterators;
};
} // namespace formatters
} // namespace lldb_private

lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
    LibcxxStdListSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp), m_list_capping_size(0),
      m_loop_detected(0), m_node_address(), m_head(nullptr), m_tail(nullptr),
      m_element_type(), m_count(UINT32_MAX), m_iterators() {
  if (valobj_sp)
    Update();
}

bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::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(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;
}

size_t lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::
    CalculateNumChildren() {
  if (m_count != UINT32_MAX)
    return m_count;
  if (!m_head || !m_tail || m_node_address == 0)
    return 0;
  ValueObjectSP size_alloc(
      m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true));
  if (size_alloc) {
    ValueObjectSP first(
        size_alloc->GetChildMemberWithName(ConstString("__first_"), true));
    if (first) {
      m_count = first->GetValueAsUnsigned(UINT32_MAX);
    }
  }
  if (m_count != UINT32_MAX) {
    return m_count;
  } else {
    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 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
lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::GetChildAtIndex(
    size_t idx) {
  static ConstString g_value("__value_");
  static ConstString g_next("__next_");

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

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

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

  size_t actual_advance = idx;

  ListIterator current(m_head);
  if (idx > 0) {
    auto cached_iterator = m_iterators.find(idx - 1);
    if (cached_iterator != m_iterators.end()) {
      current = cached_iterator->second;
      actual_advance = 1;
    }
  }

  ValueObjectSP current_sp(current.advance(actual_advance));
  if (!current_sp)
    return lldb::ValueObjectSP();

  m_iterators[idx] = current;

  current_sp = current_sp->GetChildAtIndex(1, true); // 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 nullptr;

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

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

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

bool lldb_private::formatters::LibcxxStdListSyntheticFrontEnd::Update() {
  m_iterators.clear();
  m_head = m_tail = nullptr;
  m_node_address = 0;
  m_count = UINT32_MAX;
  m_loop_detected = 0;
  m_slow_runner.SetEntry(nullptr);
  m_fast_runner.SetEntry(nullptr);

  Error err;
  ValueObjectSP backend_addr(m_backend.AddressOf(err));
  m_list_capping_size = 0;
  if (m_backend.GetTargetSP())
    m_list_capping_size =
        m_backend.GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
  if (m_list_capping_size == 0)
    m_list_capping_size = 255;
  if (err.Fail() || !backend_addr)
    return false;
  m_node_address = backend_addr->GetValueAsUnsigned(0);
  if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS)
    return false;
  ValueObjectSP impl_sp(
      m_backend.GetChildMemberWithName(ConstString("__end_"), true));
  if (!impl_sp)
    return false;
  CompilerType list_type = m_backend.GetCompilerType();
  if (list_type.IsReferenceType())
    list_type = list_type.GetNonReferenceType();

  if (list_type.GetNumTemplateArguments() == 0)
    return false;
  lldb::TemplateArgumentKind kind;
  m_element_type = list_type.GetTemplateArgument(0, kind);
  m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get();
  m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get();
  return false;
}

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

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

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