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

#include "lldb/DataFormatters/FormattersHelpers.h"
#include "llvm/Support/ErrorExtras.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;

namespace {

class MsvcStlExpectedFrontend : public SyntheticChildrenFrontEnd {
public:
  MsvcStlExpectedFrontend(ValueObject &valobj)
      : SyntheticChildrenFrontEnd(valobj) {
    if (valobj.GetTargetSP())
      Update();
  }

  llvm::Expected<size_t> GetIndexOfChildWithName(ConstString name) override {
    if (!m_active)
      return llvm::createStringErrorV("type has no child named '{0}'", name);
    if (m_has_value) {
      if (name == "Value" || name == "$$dereference$$")
        return 0;
    } else if (name == "Unexpected") {
      return 0;
    }
    return llvm::createStringErrorV("type has no child named '{0}'", name);
  }

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

  ValueObjectSP GetChildAtIndex(uint32_t idx) override {
    if (!m_active || idx != 0)
      return {};
    return m_active->Clone(m_has_value ? "Value" : "Unexpected");
  }

  lldb::ChildCacheState Update() override {
    m_active = nullptr;
    m_has_value = false;
    ValueObjectSP ns = m_backend.GetNonSyntheticValue();
    if (!ns)
      return lldb::ChildCacheState::eRefetch;

    ValueObjectSP has_sp = ns->GetChildMemberWithName("_Has_value");
    if (!has_sp)
      return lldb::ChildCacheState::eRefetch;

    m_has_value = has_sp->GetValueAsUnsigned(0) != 0;
    // expected<void, E> has no value child when engaged.
    m_active =
        ns->GetChildMemberWithName(m_has_value ? "_Value" : "_Unexpected")
            .get();
    return lldb::ChildCacheState::eRefetch;
  }

private:
  ValueObject *m_active = nullptr;
  bool m_has_value = false;
};
} // namespace

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

bool formatters::MsvcStlExpectedSummaryProvider(ValueObject &valobj,
                                                Stream &stream,
                                                const TypeSummaryOptions &) {
  ValueObjectSP ns = valobj.GetNonSyntheticValue();
  if (!ns)
    return false;
  ValueObjectSP has_sp = ns->GetChildMemberWithName("_Has_value");
  if (!has_sp)
    return false;
  // Keep the summary consistent with std::optional.
  stream.Printf(" Has Value=%s ",
                has_sp->GetValueAsUnsigned(0) ? "true" : "false");
  return true;
}

SyntheticChildrenFrontEnd *formatters::MsvcStlExpectedSyntheticFrontEndCreator(
    CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
  if (valobj_sp)
    return new MsvcStlExpectedFrontend(*valobj_sp);
  return nullptr;
}
