//===-- GenericOptional.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 "Generic.h"
#include "LibCxx.h"
#include "LibStdcpp.h"
#include "MsvcStl.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Target/Target.h"

using namespace lldb;
using namespace lldb_private;

bool lldb_private::formatters::GenericOptionalSummaryProvider(
    ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
  stream.Printf(" Has Value=%s ",
                valobj.GetNumChildrenIgnoringErrors() == 0 ? "false" : "true");

  return true;
}

// Synthetic Children Provider
namespace {

class GenericOptionalFrontend : public SyntheticChildrenFrontEnd {
public:
  enum class StdLib {
    LibCxx,
    LibStdcpp,
    MsvcStl,
  };

  GenericOptionalFrontend(ValueObject &valobj, StdLib stdlib);

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override {
    if (name == "$$dereference$$")
      return 0;
    auto optional_idx = formatters::ExtractIndexFromString(name.GetCString());
    if (!optional_idx) {
      return llvm::createStringError("Type has no child named '%s'",
                                     name.AsCString());
    }
    return *optional_idx;
  }

  llvm::Expected<uint32_t> CalculateNumChildren() override {
    return m_has_value ? 1U : 0U;
  }

  ValueObjectSP GetChildAtIndex(uint32_t idx) override;
  lldb::ChildCacheState Update() override;

private:
  bool m_has_value = false;
  StdLib m_stdlib;
};

} // namespace

GenericOptionalFrontend::GenericOptionalFrontend(ValueObject &valobj,
                                                 StdLib stdlib)
    : SyntheticChildrenFrontEnd(valobj), m_stdlib(stdlib) {
  if (auto target_sp = m_backend.GetTargetSP()) {
    Update();
  }
}

lldb::ChildCacheState GenericOptionalFrontend::Update() {
  ValueObjectSP engaged_sp;

  if (m_stdlib == StdLib::LibCxx)
    engaged_sp = m_backend.GetChildMemberWithName("__engaged_");
  else if (m_stdlib == StdLib::LibStdcpp) {
    if (ValueObjectSP payload = m_backend.GetChildMemberWithName("_M_payload"))
      engaged_sp = payload->GetChildMemberWithName("_M_engaged");
  } else if (m_stdlib == StdLib::MsvcStl)
    engaged_sp = m_backend.GetChildMemberWithName("_Has_value");

  if (!engaged_sp)
    return lldb::ChildCacheState::eRefetch;

  // _M_engaged/__engaged is a bool flag and is true if the optional contains a
  // value. Converting it to unsigned gives us a size of 1 if it contains a
  // value and 0 if not.
  m_has_value = engaged_sp->GetValueAsUnsigned(0) != 0;

  return lldb::ChildCacheState::eRefetch;
}

ValueObjectSP GenericOptionalFrontend::GetChildAtIndex(uint32_t _idx) {
  if (!m_has_value)
    return ValueObjectSP();

  ValueObjectSP val_sp;

  if (m_stdlib == StdLib::LibCxx)
    // __val_ contains the underlying value of an optional if it has one.
    // Currently because it is part of an anonymous union
    // GetChildMemberWithName() does not peer through and find it unless we are
    // at the parent itself. We can obtain the parent through __engaged_.
    val_sp = m_backend.GetChildMemberWithName("__engaged_")
                 ->GetParent()
                 ->GetChildAtIndex(0)
                 ->GetChildMemberWithName("__val_");
  else if (m_stdlib == StdLib::LibStdcpp) {
    val_sp = m_backend.GetChildMemberWithName("_M_payload")
                 ->GetChildMemberWithName("_M_payload");

    // In some implementations, _M_value contains the underlying value of an
    // optional, and in other versions, it's in the payload member.
    ValueObjectSP candidate = val_sp->GetChildMemberWithName("_M_value");
    if (candidate)
      val_sp = candidate;
  } else if (m_stdlib == StdLib::MsvcStl)
    // Same issue as with LibCxx
    val_sp = m_backend.GetChildMemberWithName("_Has_value")
                 ->GetParent()
                 ->GetChildAtIndex(0)
                 ->GetChildMemberWithName("_Value");

  if (!val_sp)
    return ValueObjectSP();

  CompilerType holder_type = val_sp->GetCompilerType();

  if (!holder_type)
    return ValueObjectSP();

  return val_sp->Clone(ConstString("Value"));
}

SyntheticChildrenFrontEnd *
formatters::LibStdcppOptionalSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  if (valobj_sp)
    return new GenericOptionalFrontend(
        *valobj_sp, GenericOptionalFrontend::StdLib::LibStdcpp);
  return nullptr;
}

SyntheticChildrenFrontEnd *formatters::LibcxxOptionalSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  if (valobj_sp)
    return new GenericOptionalFrontend(*valobj_sp,
                                       GenericOptionalFrontend::StdLib::LibCxx);
  return nullptr;
}

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

SyntheticChildrenFrontEnd *formatters::MsvcStlOptionalSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  if (valobj_sp)
    return new GenericOptionalFrontend(
        *valobj_sp, GenericOptionalFrontend::StdLib::MsvcStl);
  return nullptr;
}
