//===-- MsvcStlDeque.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/DataFormatters/TypeSynthetic.h"
#include "lldb/Utility/LLDBLog.h"
#include "llvm/Support/ErrorExtras.h"

using namespace lldb;

namespace lldb_private {
namespace formatters {

class MsvcStlDequeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  MsvcStlDequeSyntheticFrontEnd(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:
  ValueObject *m_map = nullptr;
  ExecutionContextRef m_exe_ctx_ref;

  size_t m_block_size = 0;
  size_t m_offset = 0;
  size_t m_map_size = 0;

  size_t m_element_size = 0;
  CompilerType m_element_type;

  uint32_t m_size = 0;
};

} // namespace formatters
} // namespace lldb_private

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

llvm::Expected<uint32_t> lldb_private::formatters::
    MsvcStlDequeSyntheticFrontEnd::CalculateNumChildren() {
  if (!m_map)
    return llvm::createStringError("failed to read size");
  return m_size;
}

lldb::ValueObjectSP
lldb_private::formatters::MsvcStlDequeSyntheticFrontEnd::GetChildAtIndex(
    uint32_t idx) {
  if (idx >= m_size || !m_map)
    return nullptr;
  ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
  if (!process_sp)
    return nullptr;

  // _EEN_DS = _Block_size
  // _Map[(($i + _Myoff) / _EEN_DS) % _Mapsize][($i + _Myoff) % _EEN_DS]
  size_t first_idx = ((idx + m_offset) / m_block_size) % m_map_size;
  lldb::addr_t first_address = m_map->GetValueAsUnsigned(0) +
                               first_idx * process_sp->GetAddressByteSize();

  Status err;
  lldb::addr_t second_base =
      process_sp->ReadPointerFromMemory(first_address, err);
  if (err.Fail())
    return nullptr;

  size_t second_idx = (idx + m_offset) % m_block_size;
  size_t second_address = second_base + second_idx * m_element_size;

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

lldb::ChildCacheState
lldb_private::formatters::MsvcStlDequeSyntheticFrontEnd::Update() {
  m_size = 0;
  m_map = nullptr;
  m_element_type.Clear();

  ValueObjectSP storage_sp =
      m_backend.GetChildAtNamePath({"_Mypair", "_Myval2"});
  if (!storage_sp)
    return lldb::eRefetch;

  CompilerType deque_type = m_backend.GetCompilerType();
  if (!deque_type)
    return lldb::eRefetch;

  CompilerDecl block_size_decl =
      deque_type.GetStaticFieldWithName("_Block_size");
  if (!block_size_decl)
    return lldb::eRefetch;
  Scalar block_size = block_size_decl.GetConstantValue();
  if (!block_size.IsValid() || block_size <= 0)
    return lldb::eRefetch;

  ValueObjectSP offset_sp = storage_sp->GetChildMemberWithName("_Myoff");
  ValueObjectSP map_size_sp = storage_sp->GetChildMemberWithName("_Mapsize");
  ValueObjectSP map_sp = storage_sp->GetChildMemberWithName("_Map");
  ValueObjectSP size_sp = storage_sp->GetChildMemberWithName("_Mysize");
  if (!offset_sp || !map_size_sp || !map_sp || !size_sp)
    return lldb::eRefetch;

  bool ok = false;
  uint64_t offset = offset_sp->GetValueAsUnsigned(0, &ok);
  if (!ok)
    return lldb::eRefetch;

  uint64_t map_size = map_size_sp->GetValueAsUnsigned(0, &ok);
  if (!ok || map_size == 0)
    return lldb::eRefetch;

  uint64_t size = size_sp->GetValueAsUnsigned(0, &ok);
  if (!ok)
    return lldb::eRefetch;

  CompilerType element_type = deque_type.GetTypeTemplateArgument(0);
  if (!element_type) {
    // PDB doesn't have the template type, so use the type of _Map (T**).
    element_type = map_sp->GetCompilerType().GetPointeeType().GetPointeeType();
    if (!element_type)
      return lldb::eRefetch;
  }
  auto element_size_or_err = element_type.GetByteSize(nullptr);
  if (!element_size_or_err) {
    LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters),
                   element_size_or_err.takeError(),
                   "failed to get deque element byte size: {0}");
    return lldb::eRefetch;
  }

  m_map = map_sp.get();
  m_exe_ctx_ref = m_backend.GetExecutionContextRef();
  m_block_size = block_size.ULongLong();
  m_offset = offset;
  m_map_size = map_size;
  m_element_size = *element_size_or_err;
  m_element_type = element_type;
  m_size = size;
  return lldb::eRefetch;
}

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

  return llvm::createStringErrorV("type has no child named '{0}'", name);
}

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

lldb_private::SyntheticChildrenFrontEnd *
lldb_private::formatters::MsvcStlDequeSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  return new MsvcStlDequeSyntheticFrontEnd(valobj_sp);
}
