//===-- 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 <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::createStringError("Type has no child named '%s'",
                                   name.AsCString());
  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_private::SyntheticChildrenFrontEnd *
lldb_private::formatters::LibcxxStdSliceArraySyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  if (!valobj_sp)
    return nullptr;
  return new LibcxxStdSliceArraySyntheticFrontEnd(valobj_sp);
}
