//===---------------------------------------------------------------------===//
//
// 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 "LibStdcpp.h"

#include "lldb/DataFormatters/TypeSynthetic.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/ValueObject/ValueObject.h"
#include "lldb/lldb-enumerations.h"
#include "llvm/Support/Error.h"

using namespace lldb;

namespace lldb_private::formatters {

class LibStdcppAtomicSyntheticFrontEnd final
    : public SyntheticChildrenFrontEnd {
public:
  explicit LibStdcppAtomicSyntheticFrontEnd(ValueObject &valobj)
      : SyntheticChildrenFrontEnd(valobj) {}

  llvm::Expected<uint32_t> CalculateNumChildren() override {
    if (!m_inner)
      return llvm::createStringError("Invalid atomic ValueObject.");
    return 1;
  }

  ValueObjectSP GetChildAtIndex(uint32_t idx) override {
    if (idx == 0 && m_inner)
      return m_inner->GetSP()->Clone(k_inner_name);

    return {};
  }

  lldb::ChildCacheState Update() override {
    if (ValueObjectSP value = ContainerFieldName(m_backend)) {
      // show the Type, instead of std::__atomic_base<Type>::__Type_type.
      value = value->Cast(value->GetCompilerType().GetCanonicalType());
      m_inner = value.get();
    }

    return lldb::ChildCacheState::eRefetch;
  }

  llvm::Expected<size_t>
  GetIndexOfChildWithName(llvm::StringRef name) override {
    if (name == k_inner_name)
      return 0;

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

  static ValueObjectSP ContainerFieldName(ValueObject &backend_syn) {
    const ValueObjectSP non_synthetic = backend_syn.GetNonSyntheticValue();
    if (!non_synthetic)
      return {};
    ValueObject &backend = *non_synthetic;

    const CompilerType type = backend.GetCompilerType();
    if (!type || type.GetNumTemplateArguments() == 0)
      return {};

    const CompilerType first_type = type.GetTypeTemplateArgument(0);
    if (!first_type)
      return {};

    if (first_type.IsBoolean())
      return backend.GetChildAtNamePath({"_M_base", "_M_i"});

    const uint32_t float_mask = lldb::eTypeIsFloat | lldb::eTypeIsBuiltIn;
    if ((first_type.GetTypeInfo() & float_mask) == float_mask) {
      // added float types specialization in c++20
      if (const auto child = backend.GetChildMemberWithName("_M_fp"))
        return child;

      return backend.GetChildMemberWithName("_M_i");
    }

    if (first_type.IsPointerType())
      return backend.GetChildAtNamePath({"_M_b", "_M_p"});

    const auto first_typename = first_type.GetDisplayTypeName().GetStringRef();
    if (first_typename.starts_with("std::shared_ptr<") ||
        first_typename.starts_with("std::weak_ptr<"))
      return backend.GetChildAtNamePath({"_M_impl", "_M_ptr"});

    return backend.GetChildMemberWithName("_M_i");
  }

private:
  inline static const ConstString k_inner_name = ConstString("Value");
  ValueObject *m_inner = nullptr;
};

SyntheticChildrenFrontEnd *
LibStdcppAtomicSyntheticFrontEndCreator(CXXSyntheticChildren * /*unused*/,
                                        const lldb::ValueObjectSP &valobj_sp) {
  if (!valobj_sp)
    return nullptr;

  const ValueObjectSP member =
      LibStdcppAtomicSyntheticFrontEnd::ContainerFieldName(*valobj_sp);
  if (!member)
    return nullptr;

  return new LibStdcppAtomicSyntheticFrontEnd(*valobj_sp);
}

bool LibStdcppAtomicSummaryProvider(ValueObject &valobj, Stream &stream,
                                    const TypeSummaryOptions &options) {

  if (const ValueObjectSP atomic_value =
          LibStdcppAtomicSyntheticFrontEnd::ContainerFieldName(valobj)) {
    std::string summary;
    if (atomic_value->GetSummaryAsCString(summary, options) &&
        !summary.empty()) {
      stream << summary;
      return true;
    }

    ValueObject *aparent = atomic_value->GetParent();
    if (aparent && aparent->GetName() == "_M_impl") {
      return LibStdcppSmartPointerSummaryProvider(*aparent, stream, options,
                                                  /*is_atomic_child=*/true);
    }
  }

  return false;
}

} // namespace lldb_private::formatters
