//===-- SBTypeCategory.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/API/SBTypeCategory.h"
#include "lldb/Utility/Instrumentation.h"

#include "lldb/API/SBStream.h"
#include "lldb/API/SBTypeFilter.h"
#include "lldb/API/SBTypeFormat.h"
#include "lldb/API/SBTypeNameSpecifier.h"
#include "lldb/API/SBTypeSummary.h"
#include "lldb/API/SBTypeSynthetic.h"

#include "lldb/Core/Debugger.h"
#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/ScriptInterpreter.h"

using namespace lldb;
using namespace lldb_private;

typedef std::pair<lldb::TypeCategoryImplSP, user_id_t> ImplType;

SBTypeCategory::SBTypeCategory() { LLDB_INSTRUMENT_VA(this); }

SBTypeCategory::SBTypeCategory(const char *name) {
  DataVisualization::Categories::GetCategory(ConstString(name), m_opaque_sp);
}

SBTypeCategory::SBTypeCategory(const lldb::SBTypeCategory &rhs)
    : m_opaque_sp(rhs.m_opaque_sp) {
  LLDB_INSTRUMENT_VA(this, rhs);
}

SBTypeCategory::~SBTypeCategory() = default;

bool SBTypeCategory::IsValid() const {
  LLDB_INSTRUMENT_VA(this);
  return this->operator bool();
}
SBTypeCategory::operator bool() const {
  LLDB_INSTRUMENT_VA(this);

  return (m_opaque_sp.get() != nullptr);
}

bool SBTypeCategory::GetEnabled() {
  LLDB_INSTRUMENT_VA(this);

  if (!IsValid())
    return false;
  return m_opaque_sp->IsEnabled();
}

void SBTypeCategory::SetEnabled(bool enabled) {
  LLDB_INSTRUMENT_VA(this, enabled);

  if (!IsValid())
    return;
  if (enabled)
    DataVisualization::Categories::Enable(m_opaque_sp);
  else
    DataVisualization::Categories::Disable(m_opaque_sp);
}

const char *SBTypeCategory::GetName() {
  LLDB_INSTRUMENT_VA(this);

  if (!IsValid())
    return nullptr;
  return m_opaque_sp->GetName();
}

lldb::LanguageType SBTypeCategory::GetLanguageAtIndex(uint32_t idx) {
  LLDB_INSTRUMENT_VA(this, idx);

  if (IsValid())
    return m_opaque_sp->GetLanguageAtIndex(idx);
  return lldb::eLanguageTypeUnknown;
}

uint32_t SBTypeCategory::GetNumLanguages() {
  LLDB_INSTRUMENT_VA(this);

  if (IsValid())
    return m_opaque_sp->GetNumLanguages();
  return 0;
}

void SBTypeCategory::AddLanguage(lldb::LanguageType language) {
  LLDB_INSTRUMENT_VA(this, language);

  if (IsValid())
    m_opaque_sp->AddLanguage(language);
}

uint32_t SBTypeCategory::GetNumFormats() {
  LLDB_INSTRUMENT_VA(this);

  if (!IsValid())
    return 0;

  return m_opaque_sp->GetTypeFormatsContainer()->GetCount() +
         m_opaque_sp->GetRegexTypeFormatsContainer()->GetCount();
}

uint32_t SBTypeCategory::GetNumSummaries() {
  LLDB_INSTRUMENT_VA(this);

  if (!IsValid())
    return 0;
  return m_opaque_sp->GetTypeSummariesContainer()->GetCount() +
         m_opaque_sp->GetRegexTypeSummariesContainer()->GetCount();
}

uint32_t SBTypeCategory::GetNumFilters() {
  LLDB_INSTRUMENT_VA(this);

  if (!IsValid())
    return 0;
  return m_opaque_sp->GetTypeFiltersContainer()->GetCount() +
         m_opaque_sp->GetRegexTypeFiltersContainer()->GetCount();
}

uint32_t SBTypeCategory::GetNumSynthetics() {
  LLDB_INSTRUMENT_VA(this);

  if (!IsValid())
    return 0;
  return m_opaque_sp->GetTypeSyntheticsContainer()->GetCount() +
         m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetCount();
}

lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForFilterAtIndex(uint32_t index) {
  LLDB_INSTRUMENT_VA(this, index);

  if (!IsValid())
    return SBTypeNameSpecifier();
  return SBTypeNameSpecifier(
      m_opaque_sp->GetTypeNameSpecifierForFilterAtIndex(index));
}

lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForFormatAtIndex(uint32_t index) {
  LLDB_INSTRUMENT_VA(this, index);

  if (!IsValid())
    return SBTypeNameSpecifier();
  return SBTypeNameSpecifier(
      m_opaque_sp->GetTypeNameSpecifierForFormatAtIndex(index));
}

lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForSummaryAtIndex(uint32_t index) {
  LLDB_INSTRUMENT_VA(this, index);

  if (!IsValid())
    return SBTypeNameSpecifier();
  return SBTypeNameSpecifier(
      m_opaque_sp->GetTypeNameSpecifierForSummaryAtIndex(index));
}

lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForSyntheticAtIndex(uint32_t index) {
  LLDB_INSTRUMENT_VA(this, index);

  if (!IsValid())
    return SBTypeNameSpecifier();
  return SBTypeNameSpecifier(
      m_opaque_sp->GetTypeNameSpecifierForSyntheticAtIndex(index));
}

SBTypeFilter SBTypeCategory::GetFilterForType(SBTypeNameSpecifier spec) {
  LLDB_INSTRUMENT_VA(this, spec);

  if (!IsValid())
    return SBTypeFilter();

  if (!spec.IsValid())
    return SBTypeFilter();

  lldb::TypeFilterImplSP children_sp;

  if (spec.IsRegex())
    m_opaque_sp->GetRegexTypeFiltersContainer()->GetExact(
        ConstString(spec.GetName()), children_sp);
  else
    m_opaque_sp->GetTypeFiltersContainer()->GetExact(
        ConstString(spec.GetName()), children_sp);

  if (!children_sp)
    return lldb::SBTypeFilter();

  TypeFilterImplSP filter_sp =
      std::static_pointer_cast<TypeFilterImpl>(children_sp);

  return lldb::SBTypeFilter(filter_sp);
}
SBTypeFormat SBTypeCategory::GetFormatForType(SBTypeNameSpecifier spec) {
  LLDB_INSTRUMENT_VA(this, spec);

  if (!IsValid())
    return SBTypeFormat();

  if (!spec.IsValid())
    return SBTypeFormat();

  lldb::TypeFormatImplSP format_sp;

  if (spec.IsRegex())
    m_opaque_sp->GetRegexTypeFormatsContainer()->GetExact(
        ConstString(spec.GetName()), format_sp);
  else
    m_opaque_sp->GetTypeFormatsContainer()->GetExact(
        ConstString(spec.GetName()), format_sp);

  if (!format_sp)
    return lldb::SBTypeFormat();

  return lldb::SBTypeFormat(format_sp);
}

SBTypeSummary SBTypeCategory::GetSummaryForType(SBTypeNameSpecifier spec) {
  LLDB_INSTRUMENT_VA(this, spec);

  if (!IsValid())
    return SBTypeSummary();

  if (!spec.IsValid())
    return SBTypeSummary();

  lldb::TypeSummaryImplSP summary_sp;

  if (spec.IsRegex())
    m_opaque_sp->GetRegexTypeSummariesContainer()->GetExact(
        ConstString(spec.GetName()), summary_sp);
  else
    m_opaque_sp->GetTypeSummariesContainer()->GetExact(
        ConstString(spec.GetName()), summary_sp);

  if (!summary_sp)
    return lldb::SBTypeSummary();

  return lldb::SBTypeSummary(summary_sp);
}

SBTypeSynthetic SBTypeCategory::GetSyntheticForType(SBTypeNameSpecifier spec) {
  LLDB_INSTRUMENT_VA(this, spec);

  if (!IsValid())
    return SBTypeSynthetic();

  if (!spec.IsValid())
    return SBTypeSynthetic();

  lldb::SyntheticChildrenSP children_sp;

  if (spec.IsRegex())
    m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetExact(
        ConstString(spec.GetName()), children_sp);
  else
    m_opaque_sp->GetTypeSyntheticsContainer()->GetExact(
        ConstString(spec.GetName()), children_sp);

  if (!children_sp)
    return lldb::SBTypeSynthetic();

  ScriptedSyntheticChildrenSP synth_sp =
      std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);

  return lldb::SBTypeSynthetic(synth_sp);
}

SBTypeFilter SBTypeCategory::GetFilterAtIndex(uint32_t index) {
  LLDB_INSTRUMENT_VA(this, index);

  if (!IsValid())
    return SBTypeFilter();
  lldb::SyntheticChildrenSP children_sp =
      m_opaque_sp->GetSyntheticAtIndex((index));

  if (!children_sp.get())
    return lldb::SBTypeFilter();

  TypeFilterImplSP filter_sp =
      std::static_pointer_cast<TypeFilterImpl>(children_sp);

  return lldb::SBTypeFilter(filter_sp);
}

SBTypeFormat SBTypeCategory::GetFormatAtIndex(uint32_t index) {
  LLDB_INSTRUMENT_VA(this, index);

  if (!IsValid())
    return SBTypeFormat();
  return SBTypeFormat(m_opaque_sp->GetFormatAtIndex((index)));
}

SBTypeSummary SBTypeCategory::GetSummaryAtIndex(uint32_t index) {
  LLDB_INSTRUMENT_VA(this, index);

  if (!IsValid())
    return SBTypeSummary();
  return SBTypeSummary(m_opaque_sp->GetSummaryAtIndex((index)));
}

SBTypeSynthetic SBTypeCategory::GetSyntheticAtIndex(uint32_t index) {
  LLDB_INSTRUMENT_VA(this, index);

  if (!IsValid())
    return SBTypeSynthetic();
  lldb::SyntheticChildrenSP children_sp =
      m_opaque_sp->GetSyntheticAtIndex((index));

  if (!children_sp.get())
    return lldb::SBTypeSynthetic();

  ScriptedSyntheticChildrenSP synth_sp =
      std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);

  return lldb::SBTypeSynthetic(synth_sp);
}

bool SBTypeCategory::AddTypeFormat(SBTypeNameSpecifier type_name,
                                   SBTypeFormat format) {
  LLDB_INSTRUMENT_VA(this, type_name, format);

  if (!IsValid())
    return false;

  if (!type_name.IsValid())
    return false;

  if (!format.IsValid())
    return false;

  if (type_name.IsRegex())
    m_opaque_sp->GetRegexTypeFormatsContainer()->Add(
        RegularExpression(type_name.GetName()), format.GetSP());
  else
    m_opaque_sp->GetTypeFormatsContainer()->Add(
        ConstString(type_name.GetName()), format.GetSP());

  return true;
}

bool SBTypeCategory::DeleteTypeFormat(SBTypeNameSpecifier type_name) {
  LLDB_INSTRUMENT_VA(this, type_name);

  if (!IsValid())
    return false;

  if (!type_name.IsValid())
    return false;

  if (type_name.IsRegex())
    return m_opaque_sp->GetRegexTypeFormatsContainer()->Delete(
        ConstString(type_name.GetName()));
  else
    return m_opaque_sp->GetTypeFormatsContainer()->Delete(
        ConstString(type_name.GetName()));
}

bool SBTypeCategory::AddTypeSummary(SBTypeNameSpecifier type_name,
                                    SBTypeSummary summary) {
  LLDB_INSTRUMENT_VA(this, type_name, summary);

  if (!IsValid())
    return false;

  if (!type_name.IsValid())
    return false;

  if (!summary.IsValid())
    return false;

  // FIXME: we need to iterate over all the Debugger objects and have each of
  // them contain a copy of the function
  // since we currently have formatters live in a global space, while Python
  // code lives in a specific Debugger-related environment this should
  // eventually be fixed by deciding a final location in the LLDB object space
  // for formatters
  if (summary.IsFunctionCode()) {
    const void *name_token =
        (const void *)ConstString(type_name.GetName()).GetCString();
    const char *script = summary.GetData();
    StringList input;
    input.SplitIntoLines(script, strlen(script));
    uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers();
    bool need_set = true;
    for (uint32_t j = 0; j < num_debuggers; j++) {
      DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j);
      if (debugger_sp) {
        ScriptInterpreter *interpreter_ptr =
            debugger_sp->GetScriptInterpreter();
        if (interpreter_ptr) {
          std::string output;
          if (interpreter_ptr->GenerateTypeScriptFunction(input, output,
                                                          name_token) &&
              !output.empty()) {
            if (need_set) {
              need_set = false;
              summary.SetFunctionName(output.c_str());
            }
          }
        }
      }
    }
  }

  if (type_name.IsRegex())
    m_opaque_sp->GetRegexTypeSummariesContainer()->Add(
        RegularExpression(type_name.GetName()), summary.GetSP());
  else
    m_opaque_sp->GetTypeSummariesContainer()->Add(
        ConstString(type_name.GetName()), summary.GetSP());

  return true;
}

bool SBTypeCategory::DeleteTypeSummary(SBTypeNameSpecifier type_name) {
  LLDB_INSTRUMENT_VA(this, type_name);

  if (!IsValid())
    return false;

  if (!type_name.IsValid())
    return false;

  if (type_name.IsRegex())
    return m_opaque_sp->GetRegexTypeSummariesContainer()->Delete(
        ConstString(type_name.GetName()));
  else
    return m_opaque_sp->GetTypeSummariesContainer()->Delete(
        ConstString(type_name.GetName()));
}

bool SBTypeCategory::AddTypeFilter(SBTypeNameSpecifier type_name,
                                   SBTypeFilter filter) {
  LLDB_INSTRUMENT_VA(this, type_name, filter);

  if (!IsValid())
    return false;

  if (!type_name.IsValid())
    return false;

  if (!filter.IsValid())
    return false;

  if (type_name.IsRegex())
    m_opaque_sp->GetRegexTypeFiltersContainer()->Add(
        RegularExpression(type_name.GetName()), filter.GetSP());
  else
    m_opaque_sp->GetTypeFiltersContainer()->Add(
        ConstString(type_name.GetName()), filter.GetSP());

  return true;
}

bool SBTypeCategory::DeleteTypeFilter(SBTypeNameSpecifier type_name) {
  LLDB_INSTRUMENT_VA(this, type_name);

  if (!IsValid())
    return false;

  if (!type_name.IsValid())
    return false;

  if (type_name.IsRegex())
    return m_opaque_sp->GetRegexTypeFiltersContainer()->Delete(
        ConstString(type_name.GetName()));
  else
    return m_opaque_sp->GetTypeFiltersContainer()->Delete(
        ConstString(type_name.GetName()));
}

bool SBTypeCategory::AddTypeSynthetic(SBTypeNameSpecifier type_name,
                                      SBTypeSynthetic synth) {
  LLDB_INSTRUMENT_VA(this, type_name, synth);

  if (!IsValid())
    return false;

  if (!type_name.IsValid())
    return false;

  if (!synth.IsValid())
    return false;

  // FIXME: we need to iterate over all the Debugger objects and have each of
  // them contain a copy of the function
  // since we currently have formatters live in a global space, while Python
  // code lives in a specific Debugger-related environment this should
  // eventually be fixed by deciding a final location in the LLDB object space
  // for formatters
  if (synth.IsClassCode()) {
    const void *name_token =
        (const void *)ConstString(type_name.GetName()).GetCString();
    const char *script = synth.GetData();
    StringList input;
    input.SplitIntoLines(script, strlen(script));
    uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers();
    bool need_set = true;
    for (uint32_t j = 0; j < num_debuggers; j++) {
      DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j);
      if (debugger_sp) {
        ScriptInterpreter *interpreter_ptr =
            debugger_sp->GetScriptInterpreter();
        if (interpreter_ptr) {
          std::string output;
          if (interpreter_ptr->GenerateTypeSynthClass(input, output,
                                                      name_token) &&
              !output.empty()) {
            if (need_set) {
              need_set = false;
              synth.SetClassName(output.c_str());
            }
          }
        }
      }
    }
  }

  if (type_name.IsRegex())
    m_opaque_sp->GetRegexTypeSyntheticsContainer()->Add(
        RegularExpression(type_name.GetName()), synth.GetSP());
  else
    m_opaque_sp->GetTypeSyntheticsContainer()->Add(
        ConstString(type_name.GetName()), synth.GetSP());

  return true;
}

bool SBTypeCategory::DeleteTypeSynthetic(SBTypeNameSpecifier type_name) {
  LLDB_INSTRUMENT_VA(this, type_name);

  if (!IsValid())
    return false;

  if (!type_name.IsValid())
    return false;

  if (type_name.IsRegex())
    return m_opaque_sp->GetRegexTypeSyntheticsContainer()->Delete(
        ConstString(type_name.GetName()));
  else
    return m_opaque_sp->GetTypeSyntheticsContainer()->Delete(
        ConstString(type_name.GetName()));
}

bool SBTypeCategory::GetDescription(lldb::SBStream &description,
                                    lldb::DescriptionLevel description_level) {
  LLDB_INSTRUMENT_VA(this, description, description_level);

  if (!IsValid())
    return false;
  description.Printf("Category name: %s\n", GetName());
  return true;
}

lldb::SBTypeCategory &SBTypeCategory::
operator=(const lldb::SBTypeCategory &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  if (this != &rhs) {
    m_opaque_sp = rhs.m_opaque_sp;
  }
  return *this;
}

bool SBTypeCategory::operator==(lldb::SBTypeCategory &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  if (!IsValid())
    return !rhs.IsValid();

  return m_opaque_sp.get() == rhs.m_opaque_sp.get();
}

bool SBTypeCategory::operator!=(lldb::SBTypeCategory &rhs) {
  LLDB_INSTRUMENT_VA(this, rhs);

  if (!IsValid())
    return rhs.IsValid();

  return m_opaque_sp.get() != rhs.m_opaque_sp.get();
}

lldb::TypeCategoryImplSP SBTypeCategory::GetSP() {
  if (!IsValid())
    return lldb::TypeCategoryImplSP();
  return m_opaque_sp;
}

void SBTypeCategory::SetSP(
    const lldb::TypeCategoryImplSP &typecategory_impl_sp) {
  m_opaque_sp = typecategory_impl_sp;
}

SBTypeCategory::SBTypeCategory(
    const lldb::TypeCategoryImplSP &typecategory_impl_sp)
    : m_opaque_sp(typecategory_impl_sp) {}

bool SBTypeCategory::IsDefaultCategory() {
  if (!IsValid())
    return false;

  return (strcmp(m_opaque_sp->GetName(), "default") == 0);
}
