//===-- ValueObjectSyntheticFilter.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 "lldb/Core/ValueObjectSyntheticFilter.h"

#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/DataFormatters/TypeSynthetic.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Logging.h"
#include "lldb/Utility/Status.h"

#include "llvm/ADT/STLExtras.h"

namespace lldb_private {
class Declaration;
}

using namespace lldb_private;

class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
  DummySyntheticFrontEnd(ValueObject &backend)
      : SyntheticChildrenFrontEnd(backend) {}

  size_t CalculateNumChildren() override { return m_backend.GetNumChildren(); }

  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
    return m_backend.GetChildAtIndex(idx, true);
  }

  size_t GetIndexOfChildWithName(ConstString name) override {
    return m_backend.GetIndexOfChildWithName(name);
  }

  bool MightHaveChildren() override { return true; }

  bool Update() override { return false; }
};

ValueObjectSynthetic::ValueObjectSynthetic(ValueObject &parent,
                                           lldb::SyntheticChildrenSP filter)
    : ValueObject(parent), m_synth_sp(std::move(filter)), m_children_byindex(),
      m_name_toindex(), m_synthetic_children_cache(),
      m_synthetic_children_count(UINT32_MAX),
      m_parent_type_name(parent.GetTypeName()),
      m_might_have_children(eLazyBoolCalculate),
      m_provides_value(eLazyBoolCalculate) {
  SetName(parent.GetName());
  // Copying the data of an incomplete type won't work as it has no byte size.
  if (m_parent->GetCompilerType().IsCompleteType())
    CopyValueData(m_parent);
  CreateSynthFilter();
}

ValueObjectSynthetic::~ValueObjectSynthetic() = default;

CompilerType ValueObjectSynthetic::GetCompilerTypeImpl() {
  return m_parent->GetCompilerType();
}

ConstString ValueObjectSynthetic::GetTypeName() {
  return m_parent->GetTypeName();
}

ConstString ValueObjectSynthetic::GetQualifiedTypeName() {
  return m_parent->GetQualifiedTypeName();
}

ConstString ValueObjectSynthetic::GetDisplayTypeName() {
  if (ConstString synth_name = m_synth_filter_up->GetSyntheticTypeName())
    return synth_name;

  return m_parent->GetDisplayTypeName();
}

size_t ValueObjectSynthetic::CalculateNumChildren(uint32_t max) {
  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);

  UpdateValueIfNeeded();
  if (m_synthetic_children_count < UINT32_MAX)
    return m_synthetic_children_count <= max ? m_synthetic_children_count : max;

  if (max < UINT32_MAX) {
    size_t num_children = m_synth_filter_up->CalculateNumChildren(max);
    LLDB_LOGF(log,
              "[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
              "%s and type %s, the filter returned %zu child values",
              GetName().AsCString(), GetTypeName().AsCString(), num_children);
    return num_children;
  } else {
    size_t num_children = (m_synthetic_children_count =
                               m_synth_filter_up->CalculateNumChildren(max));
    LLDB_LOGF(log,
              "[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
              "%s and type %s, the filter returned %zu child values",
              GetName().AsCString(), GetTypeName().AsCString(), num_children);
    return num_children;
  }
}

lldb::ValueObjectSP
ValueObjectSynthetic::GetDynamicValue(lldb::DynamicValueType valueType) {
  if (!m_parent)
    return lldb::ValueObjectSP();
  if (IsDynamic() && GetDynamicValueType() == valueType)
    return GetSP();
  return m_parent->GetDynamicValue(valueType);
}

bool ValueObjectSynthetic::MightHaveChildren() {
  if (m_might_have_children == eLazyBoolCalculate)
    m_might_have_children =
        (m_synth_filter_up->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
  return (m_might_have_children != eLazyBoolNo);
}

llvm::Optional<uint64_t> ValueObjectSynthetic::GetByteSize() {
  return m_parent->GetByteSize();
}

lldb::ValueType ValueObjectSynthetic::GetValueType() const {
  return m_parent->GetValueType();
}

void ValueObjectSynthetic::CreateSynthFilter() {
  ValueObject *valobj_for_frontend = m_parent;
  if (m_synth_sp->WantsDereference())
  {
    CompilerType type = m_parent->GetCompilerType();
    if (type.IsValid() && type.IsPointerOrReferenceType())
    {
      Status error;
      lldb::ValueObjectSP deref_sp = m_parent->Dereference(error);
      if (error.Success())
        valobj_for_frontend = deref_sp.get();
    }
  }
  m_synth_filter_up = (m_synth_sp->GetFrontEnd(*valobj_for_frontend));
  if (!m_synth_filter_up)
    m_synth_filter_up = std::make_unique<DummySyntheticFrontEnd>(*m_parent);
}

bool ValueObjectSynthetic::UpdateValue() {
  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);

  SetValueIsValid(false);
  m_error.Clear();

  if (!m_parent->UpdateValueIfNeeded(false)) {
    // our parent could not update.. as we are meaningless without a parent,
    // just stop
    if (m_parent->GetError().Fail())
      m_error = m_parent->GetError();
    return false;
  }

  // regenerate the synthetic filter if our typename changes
  // <rdar://problem/12424824>
  ConstString new_parent_type_name = m_parent->GetTypeName();
  if (new_parent_type_name != m_parent_type_name) {
    LLDB_LOGF(log,
              "[ValueObjectSynthetic::UpdateValue] name=%s, type changed "
              "from %s to %s, recomputing synthetic filter",
              GetName().AsCString(), m_parent_type_name.AsCString(),
              new_parent_type_name.AsCString());
    m_parent_type_name = new_parent_type_name;
    CreateSynthFilter();
  }

  // let our backend do its update
  if (!m_synth_filter_up->Update()) {
    LLDB_LOGF(log,
              "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
              "filter said caches are stale - clearing",
              GetName().AsCString());
    // filter said that cached values are stale
    {
      std::lock_guard<std::mutex> guard(m_child_mutex);
      m_children_byindex.clear();
      m_name_toindex.clear();
    }
    // usually, an object's value can change but this does not alter its
    // children count for a synthetic VO that might indeed happen, so we need
    // to tell the upper echelons that they need to come back to us asking for
    // children
    m_flags.m_children_count_valid = false;
    {
      std::lock_guard<std::mutex> guard(m_child_mutex);
      m_synthetic_children_cache.clear();
    }
    m_synthetic_children_count = UINT32_MAX;
    m_might_have_children = eLazyBoolCalculate;
  } else {
    LLDB_LOGF(log,
              "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
              "filter said caches are still valid",
              GetName().AsCString());
  }

  m_provides_value = eLazyBoolCalculate;

  lldb::ValueObjectSP synth_val(m_synth_filter_up->GetSyntheticValue());

  if (synth_val && synth_val->CanProvideValue()) {
    LLDB_LOGF(log,
              "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
              "filter said it can provide a value",
              GetName().AsCString());

    m_provides_value = eLazyBoolYes;
    CopyValueData(synth_val.get());
  } else {
    LLDB_LOGF(log,
              "[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
              "filter said it will not provide a value",
              GetName().AsCString());

    m_provides_value = eLazyBoolNo;
    // Copying the data of an incomplete type won't work as it has no byte size.
    if (m_parent->GetCompilerType().IsCompleteType())
      CopyValueData(m_parent);
  }

  SetValueIsValid(true);
  return true;
}

lldb::ValueObjectSP ValueObjectSynthetic::GetChildAtIndex(size_t idx,
                                                          bool can_create) {
  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);

  LLDB_LOGF(log,
            "[ValueObjectSynthetic::GetChildAtIndex] name=%s, retrieving "
            "child at index %zu",
            GetName().AsCString(), idx);

  UpdateValueIfNeeded();

  ValueObject *valobj;
  bool child_is_cached;
  {
    std::lock_guard<std::mutex> guard(m_child_mutex);
    auto cached_child_it = m_children_byindex.find(idx);
    child_is_cached = cached_child_it != m_children_byindex.end();
    if (child_is_cached)
      valobj = cached_child_it->second;
  }

  if (!child_is_cached) {
    if (can_create && m_synth_filter_up != nullptr) {
      LLDB_LOGF(log,
                "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
                "index %zu not cached and will be created",
                GetName().AsCString(), idx);

      lldb::ValueObjectSP synth_guy = m_synth_filter_up->GetChildAtIndex(idx);

      LLDB_LOGF(
          log,
          "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index "
          "%zu created as %p (is "
          "synthetic: %s)",
          GetName().AsCString(), idx, static_cast<void *>(synth_guy.get()),
          synth_guy.get()
              ? (synth_guy->IsSyntheticChildrenGenerated() ? "yes" : "no")
              : "no");

      if (!synth_guy)
        return synth_guy;

      {
        std::lock_guard<std::mutex> guard(m_child_mutex);
        if (synth_guy->IsSyntheticChildrenGenerated())
          m_synthetic_children_cache.push_back(synth_guy);
        m_children_byindex[idx] = synth_guy.get();
      }
      synth_guy->SetPreferredDisplayLanguageIfNeeded(
          GetPreferredDisplayLanguage());
      return synth_guy;
    } else {
      LLDB_LOGF(log,
                "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
                "index %zu not cached and cannot "
                "be created (can_create = %s, synth_filter = %p)",
                GetName().AsCString(), idx, can_create ? "yes" : "no",
                static_cast<void *>(m_synth_filter_up.get()));

      return lldb::ValueObjectSP();
    }
  } else {
    LLDB_LOGF(log,
              "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
              "index %zu cached as %p",
              GetName().AsCString(), idx, static_cast<void *>(valobj));

    return valobj->GetSP();
  }
}

lldb::ValueObjectSP
ValueObjectSynthetic::GetChildMemberWithName(ConstString name,
                                             bool can_create) {
  UpdateValueIfNeeded();

  uint32_t index = GetIndexOfChildWithName(name);

  if (index == UINT32_MAX)
    return lldb::ValueObjectSP();

  return GetChildAtIndex(index, can_create);
}

size_t ValueObjectSynthetic::GetIndexOfChildWithName(ConstString name) {
  UpdateValueIfNeeded();

  uint32_t found_index = UINT32_MAX;
  bool did_find;
  {
    std::lock_guard<std::mutex> guard(m_child_mutex);
    auto name_to_index = m_name_toindex.find(name.GetCString());
    did_find = name_to_index != m_name_toindex.end();
    if (did_find)
      found_index = name_to_index->second;
  }

  if (!did_find && m_synth_filter_up != nullptr) {
    uint32_t index = m_synth_filter_up->GetIndexOfChildWithName(name);
    if (index == UINT32_MAX)
      return index;
    std::lock_guard<std::mutex> guard(m_child_mutex);
    m_name_toindex[name.GetCString()] = index;
    return index;
  } else if (!did_find && m_synth_filter_up == nullptr)
    return UINT32_MAX;
  else /*if (iter != m_name_toindex.end())*/
    return found_index;
}

bool ValueObjectSynthetic::IsInScope() { return m_parent->IsInScope(); }

lldb::ValueObjectSP ValueObjectSynthetic::GetNonSyntheticValue() {
  return m_parent->GetSP();
}

void ValueObjectSynthetic::CopyValueData(ValueObject *source) {
  m_value = (source->UpdateValueIfNeeded(), source->GetValue());
  ExecutionContext exe_ctx(GetExecutionContextRef());
  m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get());
}

bool ValueObjectSynthetic::CanProvideValue() {
  if (!UpdateValueIfNeeded())
    return false;
  if (m_provides_value == eLazyBoolYes)
    return true;
  return m_parent->CanProvideValue();
}

bool ValueObjectSynthetic::SetValueFromCString(const char *value_str,
                                               Status &error) {
  return m_parent->SetValueFromCString(value_str, error);
}

void ValueObjectSynthetic::SetFormat(lldb::Format format) {
  if (m_parent) {
    m_parent->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
    m_parent->SetFormat(format);
  }
  this->ValueObject::SetFormat(format);
  this->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
}

void ValueObjectSynthetic::SetPreferredDisplayLanguage(
    lldb::LanguageType lang) {
  this->ValueObject::SetPreferredDisplayLanguage(lang);
  if (m_parent)
    m_parent->SetPreferredDisplayLanguage(lang);
}

lldb::LanguageType ValueObjectSynthetic::GetPreferredDisplayLanguage() {
  if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
    if (m_parent)
      return m_parent->GetPreferredDisplayLanguage();
    return lldb::eLanguageTypeUnknown;
  } else
    return m_preferred_display_language;
}

bool ValueObjectSynthetic::IsSyntheticChildrenGenerated() {
  if (m_parent)
    return m_parent->IsSyntheticChildrenGenerated();
  return false;
}

void ValueObjectSynthetic::SetSyntheticChildrenGenerated(bool b) {
  if (m_parent)
    m_parent->SetSyntheticChildrenGenerated(b);
  this->ValueObject::SetSyntheticChildrenGenerated(b);
}

bool ValueObjectSynthetic::GetDeclaration(Declaration &decl) {
  if (m_parent)
    return m_parent->GetDeclaration(decl);

  return ValueObject::GetDeclaration(decl);
}

uint64_t ValueObjectSynthetic::GetLanguageFlags() {
  if (m_parent)
    return m_parent->GetLanguageFlags();
  return this->ValueObject::GetLanguageFlags();
}

void ValueObjectSynthetic::SetLanguageFlags(uint64_t flags) {
  if (m_parent)
    m_parent->SetLanguageFlags(flags);
  else
    this->ValueObject::SetLanguageFlags(flags);
}
