//===-- 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(llvm::StringRef 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 CreateChildValueObjectFromAddress(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(llvm::StringRef name) {
  if (!m_start)
    return llvm::createStringErrorV("type has no child named '{0}'", name);
  auto optional_idx = formatters::ExtractIndexFromString(name);
  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);
}
