//===-- LibCxxSliceArray.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/ValueObject/ValueObject.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 {

bool LibcxxStdSliceArraySummaryProvider(ValueObject &valobj, Stream &stream,
                                        const TypeSummaryOptions &options) {
  ValueObjectSP obj = valobj.GetNonSyntheticValue();
  if (!obj)
    return false;

  ValueObjectSP ptr_sp = obj->GetChildMemberWithName("__size_");
  if (!ptr_sp)
    return false;
  const size_t size = ptr_sp->GetValueAsUnsigned(0);

  ptr_sp = obj->GetChildMemberWithName("__stride_");
  if (!ptr_sp)
    return false;
  const size_t stride = ptr_sp->GetValueAsUnsigned(0);

  stream.Printf("stride=%zu size=%zu", stride, size);

  return true;
}

/// Data formatter for libc++'s std::slice_array.
///
/// A slice_array is created by using:
///   operator[](std::slice slicearr);
/// and std::slice is created by:
///   slice(std::size_t start, std::size_t size, std::size_t stride);
/// The std::slice_array has the following members:
/// - __vp_ points to std::valarray::__begin_ + @a start
/// - __size_ is @a size
/// - __stride_is @a stride
class LibcxxStdSliceArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  LibcxxStdSliceArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);

  ~LibcxxStdSliceArraySyntheticFrontEnd() 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:
  /// A non-owning pointer to slice_array.__vp_.
  ValueObject *m_start = nullptr;
  /// slice_array.__size_.
  size_t m_size = 0;
  /// slice_array.__stride_.
  size_t m_stride = 0;
  /// The type of slice_array's template argument T.
  CompilerType m_element_type;
  /// The sizeof slice_array's template argument T.
  uint32_t m_element_size = 0;
};

} // namespace formatters
} // namespace lldb_private

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

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

llvm::Expected<uint32_t> lldb_private::formatters::
    LibcxxStdSliceArraySyntheticFrontEnd::CalculateNumChildren() {
  return m_size;
}

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

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

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

  CompilerType type = m_backend.GetCompilerType();
  if (type.GetNumTemplateArguments() == 0)
    return ChildCacheState::eRefetch;

  m_element_type = type.GetTypeTemplateArgument(0);
  if (std::optional<uint64_t> size =
          llvm::expectedToOptional(m_element_type.GetByteSize(nullptr)))
    m_element_size = *size;

  if (m_element_size == 0)
    return ChildCacheState::eRefetch;

  ValueObjectSP start = m_backend.GetChildMemberWithName("__vp_");
  ValueObjectSP size = m_backend.GetChildMemberWithName("__size_");
  ValueObjectSP stride = m_backend.GetChildMemberWithName("__stride_");

  if (!start || !size || !stride)
    return ChildCacheState::eRefetch;

  m_start = start.get();
  m_size = size->GetValueAsUnsigned(0);
  m_stride = stride->GetValueAsUnsigned(0);

  return ChildCacheState::eRefetch;
}

llvm::Expected<size_t>
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEnd::
    GetIndexOfChildWithName(ConstString name) {
  if (!m_start)
    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::SyntheticChildrenFrontEnd *
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;
  return new LibcxxStdSliceArraySyntheticFrontEnd(valobj_sp);
}
