//===-- TypeSynthetic.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/lldb-enumerations.h"
#include "lldb/lldb-public.h"

#include "lldb/Core/Debugger.h"
#include "lldb/DataFormatters/TypeSynthetic.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb;
using namespace lldb_private;

void TypeFilterImpl::AddExpressionPath(const std::string &path) {
  bool need_add_dot = true;
  if (path[0] == '.' || (path[0] == '-' && path[1] == '>') || path[0] == '[')
    need_add_dot = false;
  // add a '.' symbol to help forgetful users
  if (!need_add_dot)
    m_expression_paths.push_back(path);
  else
    m_expression_paths.push_back(std::string(".") + path);
}

bool TypeFilterImpl::SetExpressionPathAtIndex(size_t i,
                                              const std::string &path) {
  if (i >= GetCount())
    return false;
  bool need_add_dot = true;
  if (path[0] == '.' || (path[0] == '-' && path[1] == '>') || path[0] == '[')
    need_add_dot = false;
  // add a '.' symbol to help forgetful users
  if (!need_add_dot)
    m_expression_paths[i] = path;
  else
    m_expression_paths[i] = std::string(".") + path;
  return true;
}

size_t
TypeFilterImpl::FrontEnd::GetIndexOfChildWithName(ConstString name) {
  const char *name_cstr = name.GetCString();
  if (name_cstr) {
    for (size_t i = 0; i < filter->GetCount(); i++) {
      const char *expr_cstr = filter->GetExpressionPathAtIndex(i);
      if (expr_cstr) {
        if (*expr_cstr == '.')
          expr_cstr++;
        else if (*expr_cstr == '-' && *(expr_cstr + 1) == '>')
          expr_cstr += 2;
      }
      if (expr_cstr) {
        if (!::strcmp(name_cstr, expr_cstr))
          return i;
      }
    }
  }
  return UINT32_MAX;
}

std::string TypeFilterImpl::GetDescription() {
  StreamString sstr;
  sstr.Printf("%s%s%s {\n", Cascades() ? "" : " (not cascading)",
              SkipsPointers() ? " (skip pointers)" : "",
              SkipsReferences() ? " (skip references)" : "");

  for (size_t i = 0; i < GetCount(); i++) {
    sstr.Printf("    %s\n", GetExpressionPathAtIndex(i));
  }

  sstr.Printf("}");
  return std::string(sstr.GetString());
}

std::string CXXSyntheticChildren::GetDescription() {
  StreamString sstr;
  sstr.Printf("%s%s%s %s", Cascades() ? "" : " (not cascading)",
              SkipsPointers() ? " (skip pointers)" : "",
              SkipsReferences() ? " (skip references)" : "",
              m_description.c_str());

  return std::string(sstr.GetString());
}

lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromExpression(
    llvm::StringRef name, llvm::StringRef expression,
    const ExecutionContext &exe_ctx) {
  ValueObjectSP valobj_sp(
      ValueObject::CreateValueObjectFromExpression(name, expression, exe_ctx));
  if (valobj_sp)
    valobj_sp->SetSyntheticChildrenGenerated(true);
  return valobj_sp;
}

lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromAddress(
    llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
    CompilerType type) {
  ValueObjectSP valobj_sp(
      ValueObject::CreateValueObjectFromAddress(name, address, exe_ctx, type));
  if (valobj_sp)
    valobj_sp->SetSyntheticChildrenGenerated(true);
  return valobj_sp;
}

lldb::ValueObjectSP SyntheticChildrenFrontEnd::CreateValueObjectFromData(
    llvm::StringRef name, const DataExtractor &data,
    const ExecutionContext &exe_ctx, CompilerType type) {
  ValueObjectSP valobj_sp(
      ValueObject::CreateValueObjectFromData(name, data, exe_ctx, type));
  if (valobj_sp)
    valobj_sp->SetSyntheticChildrenGenerated(true);
  return valobj_sp;
}

ScriptedSyntheticChildren::FrontEnd::FrontEnd(std::string pclass,
                                              ValueObject &backend)
    : SyntheticChildrenFrontEnd(backend), m_python_class(pclass),
      m_wrapper_sp(), m_interpreter(nullptr) {
  if (backend.GetID() == LLDB_INVALID_UID)
    return;

  TargetSP target_sp = backend.GetTargetSP();

  if (!target_sp)
    return;

  m_interpreter = target_sp->GetDebugger().GetScriptInterpreter();

  if (m_interpreter != nullptr)
    m_wrapper_sp = m_interpreter->CreateSyntheticScriptedProvider(
        m_python_class.c_str(), backend.GetSP());
}

ScriptedSyntheticChildren::FrontEnd::~FrontEnd() = default;

lldb::ValueObjectSP
ScriptedSyntheticChildren::FrontEnd::GetChildAtIndex(size_t idx) {
  if (!m_wrapper_sp || !m_interpreter)
    return lldb::ValueObjectSP();

  return m_interpreter->GetChildAtIndex(m_wrapper_sp, idx);
}

bool ScriptedSyntheticChildren::FrontEnd::IsValid() {
  return (m_wrapper_sp && m_wrapper_sp->IsValid() && m_interpreter);
}

size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren() {
  if (!m_wrapper_sp || m_interpreter == nullptr)
    return 0;
  return m_interpreter->CalculateNumChildren(m_wrapper_sp, UINT32_MAX);
}

size_t ScriptedSyntheticChildren::FrontEnd::CalculateNumChildren(uint32_t max) {
  if (!m_wrapper_sp || m_interpreter == nullptr)
    return 0;
  return m_interpreter->CalculateNumChildren(m_wrapper_sp, max);
}

bool ScriptedSyntheticChildren::FrontEnd::Update() {
  if (!m_wrapper_sp || m_interpreter == nullptr)
    return false;

  return m_interpreter->UpdateSynthProviderInstance(m_wrapper_sp);
}

bool ScriptedSyntheticChildren::FrontEnd::MightHaveChildren() {
  if (!m_wrapper_sp || m_interpreter == nullptr)
    return false;

  return m_interpreter->MightHaveChildrenSynthProviderInstance(m_wrapper_sp);
}

size_t ScriptedSyntheticChildren::FrontEnd::GetIndexOfChildWithName(
    ConstString name) {
  if (!m_wrapper_sp || m_interpreter == nullptr)
    return UINT32_MAX;
  return m_interpreter->GetIndexOfChildWithName(m_wrapper_sp,
                                                name.GetCString());
}

lldb::ValueObjectSP ScriptedSyntheticChildren::FrontEnd::GetSyntheticValue() {
  if (!m_wrapper_sp || m_interpreter == nullptr)
    return nullptr;

  return m_interpreter->GetSyntheticValue(m_wrapper_sp);
}

ConstString ScriptedSyntheticChildren::FrontEnd::GetSyntheticTypeName() {
  if (!m_wrapper_sp || m_interpreter == nullptr)
    return ConstString();

  return m_interpreter->GetSyntheticTypeName(m_wrapper_sp);
}

std::string ScriptedSyntheticChildren::GetDescription() {
  StreamString sstr;
  sstr.Printf("%s%s%s Python class %s", Cascades() ? "" : " (not cascading)",
              SkipsPointers() ? " (skip pointers)" : "",
              SkipsReferences() ? " (skip references)" : "",
              m_python_class.c_str());

  return std::string(sstr.GetString());
}
