//===-- LibCxxVector.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 "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-forward.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorExtras.h"
#include <optional>

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

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

  ~LibcxxStdVectorSyntheticFrontEnd() override;

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

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;

private:
  lldb::ChildCacheState UpdateVectorWithLayoutSubobject(ValueObject *layout);

  ValueObject *m_start = nullptr;

  // m_finish may point to a pointer (`__end_`) or an integer (`__size_`)
  // depending on how libc++'s vector is implemented. Interpreting what is
  // pointed to is done using `m_layout`.
  ValueObject *m_finish = nullptr;
  enum class VectorLayout : bool { Pointer, Size };
  VectorLayout m_layout;
  CompilerType m_element_type;
  uint32_t m_element_size = 0;
};

class LibcxxVectorBoolSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

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

  lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override;

  lldb::ChildCacheState Update() override;

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override;

private:
  CompilerType m_bool_type;
  ExecutionContextRef m_exe_ctx_ref;
  uint64_t m_count = 0;
  lldb::addr_t m_base_data_address = 0;
  std::map<size_t, lldb::ValueObjectSP> m_children;
};

} // namespace formatters
} // namespace lldb_private

lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
    LibcxxStdVectorSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp), m_element_type() {
  if (valobj_sp)
    Update();
}

lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
    ~LibcxxStdVectorSyntheticFrontEnd() {
  // these need to stay around because they are child objects who will follow
  // their parent's life cycle
  // delete m_start;
  // delete m_finish;
}

static llvm::Expected<uint32_t>
CalculateNumChildrenUsingPointerArithmetic(ValueObject *begin, ValueObject *end,
                                           uint64_t value_type_size) {
  uint64_t start_val = begin->GetValueAsUnsigned(0);
  uint64_t finish_val = end->GetValueAsUnsigned(0);

  // A default-initialized empty vector.
  if (start_val == 0 && finish_val == 0)
    return 0;

  if (start_val == 0)
    return llvm::createStringError("invalid value for start of vector");

  if (finish_val == 0)
    return llvm::createStringError("invalid value for end of vector");

  if (start_val > finish_val)
    return llvm::createStringError(
        "start of vector data begins after end pointer");

  size_t num_children = (finish_val - start_val);
  if (num_children % value_type_size)
    return llvm::createStringError("size not multiple of element size");

  return num_children / value_type_size;
}

static llvm::Expected<uint32_t> GetNumChildren(ValueObject *size) {
  if (!size->GetCompilerType().IsInteger())
    return llvm::createStringError(
        "size data member must be a built-in integer type");
  return size->GetValueAsUnsigned(0);
}

llvm::Expected<uint32_t> lldb_private::formatters::
    LibcxxStdVectorSyntheticFrontEnd::CalculateNumChildren() {
  if (!m_start || !m_finish)
    return llvm::createStringError(
        "failed to determine start/end of vector data");

  switch (m_layout) {
  case VectorLayout::Pointer:
    return CalculateNumChildrenUsingPointerArithmetic(m_start, m_finish,
                                                      m_element_size);
  case VectorLayout::Size:
    return GetNumChildren(m_finish);
  }

  assert(false && "invalid vector layout");
  return llvm::createStringError("invalid vector layout");
}

lldb::ValueObjectSP
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex(
    uint32_t idx) {
  if (!m_start || !m_finish)
    return lldb::ValueObjectSP();

  uint64_t offset = idx * m_element_size;
  offset = offset + m_start->GetValueAsUnsigned(0);
  StreamString name;
  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
  return CreateChildValueObjectFromAddress(name.GetString(), offset,
                                           m_backend.GetExecutionContextRef(),
                                           m_element_type);
}

lldb::ChildCacheState
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() {
  m_start = m_finish = nullptr;

  // Determine if this version of libc++'s `std::vector` uses `__vector_layout`.
  ValueObjectSP layout_sp = m_backend.GetChildMemberWithName("__layout_");
  ValueObject *target = layout_sp ? layout_sp.get() : &m_backend;

  ValueObjectSP begin_sp = target->GetChildMemberWithName("__begin_");
  if (!begin_sp)
    return lldb::ChildCacheState::eRefetch;

  m_element_type = begin_sp->GetCompilerType().GetPointeeType();
  llvm::Expected<uint64_t> size_or_err = m_element_type.GetByteSize(nullptr);
  if (!size_or_err) {
    LLDB_LOG_ERRORV(GetLog(LLDBLog::DataFormatters), size_or_err.takeError(),
                    "{0}");
    return lldb::ChildCacheState::eRefetch;
  }

  m_element_size = *size_or_err;
  if (m_element_size == 0) {
    return lldb::ChildCacheState::eRefetch;
  }

  // store raw pointers or end up with a circular dependency
  m_start = begin_sp.get();

  if (ValueObjectSP end_sp = target->GetChildMemberWithName("__end_")) {
    m_finish = end_sp.get();
    m_layout = VectorLayout::Pointer;
    return lldb::ChildCacheState::eRefetch;
  }

  ValueObjectSP size_sp = target->GetChildMemberWithName("__size_");
  if (!size_sp)
    return lldb::ChildCacheState::eRefetch;

  m_finish = size_sp.get();
  m_layout = VectorLayout::Size;
  return lldb::ChildCacheState::eRefetch;
}

llvm::Expected<size_t>
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::
    GetIndexOfChildWithName(ConstString name) {
  if (!m_start || !m_finish)
    return llvm::createStringErrorV("type has no child named '{0}'", name);
  auto optional_idx = formatters::ExtractIndexFromString(name.GetCString());
  if (!optional_idx) {
    return llvm::createStringErrorV("type has no child named '{0}'", name);
  }
  return *optional_idx;
}

lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
    LibcxxVectorBoolSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
    : SyntheticChildrenFrontEnd(*valobj_sp), m_bool_type(), m_exe_ctx_ref(),
      m_children() {
  if (valobj_sp) {
    Update();
    m_bool_type =
        valobj_sp->GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeBool);
  }
}

llvm::Expected<uint32_t> lldb_private::formatters::
    LibcxxVectorBoolSyntheticFrontEnd::CalculateNumChildren() {
  return m_count;
}

lldb::ValueObjectSP
lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex(
    uint32_t idx) {
  auto iter = m_children.find(idx), end = m_children.end();
  if (iter != end)
    return iter->second;
  if (idx >= m_count)
    return {};
  if (m_base_data_address == 0 || m_count == 0)
    return {};
  if (!m_bool_type)
    return {};
  size_t byte_idx = (idx >> 3); // divide by 8 to get byte index
  size_t bit_index = (idx & 7); // efficient idx % 8 for bit index
  lldb::addr_t byte_location = m_base_data_address + byte_idx;
  ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
  if (!process_sp)
    return {};
  uint8_t byte = 0;
  uint8_t mask = 0;
  Status err;
  size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err);
  if (err.Fail() || bytes_read == 0)
    return {};
  mask = 1 << bit_index;
  bool bit_set = ((byte & mask) != 0);
  std::optional<uint64_t> size =
      llvm::expectedToOptional(m_bool_type.GetByteSize(nullptr));
  if (!size)
    return {};
  WritableDataBufferSP buffer_sp(new DataBufferHeap(*size, 0));
  if (bit_set && buffer_sp && buffer_sp->GetBytes()) {
    // regardless of endianness, anything non-zero is true
    *(buffer_sp->GetBytes()) = 1;
  }
  StreamString name;
  name.Printf("[%" PRIu64 "]", (uint64_t)idx);
  ValueObjectSP retval_sp = CreateChildValueObjectFromData(
      name.GetString(),
      DataExtractor(buffer_sp, process_sp->GetByteOrder(),
                    process_sp->GetAddressByteSize()),
      m_exe_ctx_ref, m_bool_type);
  if (retval_sp)
    m_children[idx] = retval_sp;
  return retval_sp;
}

lldb::ChildCacheState
lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update() {
  m_children.clear();
  ValueObjectSP valobj_sp = m_backend.GetSP();
  if (!valobj_sp)
    return lldb::ChildCacheState::eRefetch;
  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
  ValueObjectSP size_sp(valobj_sp->GetChildMemberWithName("__size_"));
  if (!size_sp)
    return lldb::ChildCacheState::eRefetch;
  m_count = size_sp->GetValueAsUnsigned(0);
  if (!m_count)
    return lldb::ChildCacheState::eReuse;
  ValueObjectSP begin_sp(valobj_sp->GetChildMemberWithName("__begin_"));
  if (!begin_sp) {
    m_count = 0;
    return lldb::ChildCacheState::eRefetch;
  }
  m_base_data_address = begin_sp->GetValueAsUnsigned(0);
  if (!m_base_data_address) {
    m_count = 0;
    return lldb::ChildCacheState::eRefetch;
  }
  return lldb::ChildCacheState::eRefetch;
}

llvm::Expected<size_t>
lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::
    GetIndexOfChildWithName(ConstString name) {
  if (!m_count || !m_base_data_address)
    return llvm::createStringErrorV("type has no child named '{0}'", name);
  auto optional_idx = ExtractIndexFromString(name.AsCString(nullptr));
  if (!optional_idx) {
    return llvm::createStringErrorV("type has no child named '{0}'", name);
  }
  uint32_t idx = *optional_idx;
  if (idx >= CalculateNumChildrenIgnoringErrors())
    return llvm::createStringErrorV("type has no child named '{0}'", name);
  return idx;
}

lldb_private::SyntheticChildrenFrontEnd *
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;
  CompilerType type = valobj_sp->GetCompilerType();
  if (!type.IsValid() || type.GetNumTemplateArguments() == 0)
    return nullptr;
  CompilerType arg_type = type.GetTypeTemplateArgument(0);
  if (arg_type.GetTypeName() == "bool")
    return new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp);
  return new LibcxxStdVectorSyntheticFrontEnd(valobj_sp);
}
