//===-- SBTypeCategory.cpp ----------------------------------------*- C++
//-*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/API/SBTypeCategory.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() : m_opaque_sp() {}

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

SBTypeCategory::SBTypeCategory(const lldb::SBTypeCategory &rhs)
    : m_opaque_sp(rhs.m_opaque_sp) {}

SBTypeCategory::~SBTypeCategory() {}

bool SBTypeCategory::IsValid() const { return (m_opaque_sp.get() != NULL); }

bool SBTypeCategory::GetEnabled() {
  if (!IsValid())
    return false;
  return m_opaque_sp->IsEnabled();
}

void SBTypeCategory::SetEnabled(bool enabled) {
  if (!IsValid())
    return;
  if (enabled)
    DataVisualization::Categories::Enable(m_opaque_sp);
  else
    DataVisualization::Categories::Disable(m_opaque_sp);
}

const char *SBTypeCategory::GetName() {
  if (!IsValid())
    return NULL;
  return m_opaque_sp->GetName();
}

lldb::LanguageType SBTypeCategory::GetLanguageAtIndex(uint32_t idx) {
  if (IsValid())
    return m_opaque_sp->GetLanguageAtIndex(idx);
  return lldb::eLanguageTypeUnknown;
}

uint32_t SBTypeCategory::GetNumLanguages() {
  if (IsValid())
    return m_opaque_sp->GetNumLanguages();
  return 0;
}

void SBTypeCategory::AddLanguage(lldb::LanguageType language) {
  if (IsValid())
    m_opaque_sp->AddLanguage(language);
}

uint32_t SBTypeCategory::GetNumFormats() {
  if (!IsValid())
    return 0;

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

uint32_t SBTypeCategory::GetNumSummaries() {
  if (!IsValid())
    return 0;
  return m_opaque_sp->GetTypeSummariesContainer()->GetCount() +
         m_opaque_sp->GetRegexTypeSummariesContainer()->GetCount();
}

uint32_t SBTypeCategory::GetNumFilters() {
  if (!IsValid())
    return 0;
  return m_opaque_sp->GetTypeFiltersContainer()->GetCount() +
         m_opaque_sp->GetRegexTypeFiltersContainer()->GetCount();
}

#ifndef LLDB_DISABLE_PYTHON
uint32_t SBTypeCategory::GetNumSynthetics() {
  if (!IsValid())
    return 0;
  return m_opaque_sp->GetTypeSyntheticsContainer()->GetCount() +
         m_opaque_sp->GetRegexTypeSyntheticsContainer()->GetCount();
}
#endif

lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForFilterAtIndex(uint32_t index) {
  if (!IsValid())
    return SBTypeNameSpecifier();
  return SBTypeNameSpecifier(
      m_opaque_sp->GetTypeNameSpecifierForFilterAtIndex(index));
}

lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForFormatAtIndex(uint32_t index) {
  if (!IsValid())
    return SBTypeNameSpecifier();
  return SBTypeNameSpecifier(
      m_opaque_sp->GetTypeNameSpecifierForFormatAtIndex(index));
}

lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForSummaryAtIndex(uint32_t index) {
  if (!IsValid())
    return SBTypeNameSpecifier();
  return SBTypeNameSpecifier(
      m_opaque_sp->GetTypeNameSpecifierForSummaryAtIndex(index));
}

#ifndef LLDB_DISABLE_PYTHON
lldb::SBTypeNameSpecifier
SBTypeCategory::GetTypeNameSpecifierForSyntheticAtIndex(uint32_t index) {
  if (!IsValid())
    return SBTypeNameSpecifier();
  return SBTypeNameSpecifier(
      m_opaque_sp->GetTypeNameSpecifierForSyntheticAtIndex(index));
}
#endif

SBTypeFilter SBTypeCategory::GetFilterForType(SBTypeNameSpecifier 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) {
  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);
}

#ifndef LLDB_DISABLE_PYTHON
SBTypeSummary SBTypeCategory::GetSummaryForType(SBTypeNameSpecifier 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);
}
#endif // LLDB_DISABLE_PYTHON

#ifndef LLDB_DISABLE_PYTHON
SBTypeSynthetic SBTypeCategory::GetSyntheticForType(SBTypeNameSpecifier 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);
}
#endif

#ifndef LLDB_DISABLE_PYTHON
SBTypeFilter SBTypeCategory::GetFilterAtIndex(uint32_t 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);
}
#endif

SBTypeFormat SBTypeCategory::GetFormatAtIndex(uint32_t index) {
  if (!IsValid())
    return SBTypeFormat();
  return SBTypeFormat(m_opaque_sp->GetFormatAtIndex((index)));
}

#ifndef LLDB_DISABLE_PYTHON
SBTypeSummary SBTypeCategory::GetSummaryAtIndex(uint32_t index) {
  if (!IsValid())
    return SBTypeSummary();
  return SBTypeSummary(m_opaque_sp->GetSummaryAtIndex((index)));
}
#endif

#ifndef LLDB_DISABLE_PYTHON
SBTypeSynthetic SBTypeCategory::GetSyntheticAtIndex(uint32_t 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);
}
#endif

bool SBTypeCategory::AddTypeFormat(SBTypeNameSpecifier type_name,
                                   SBTypeFormat 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(
        lldb::RegularExpressionSP(new RegularExpression(
            llvm::StringRef::withNullAsEmpty(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) {
  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()));
}

#ifndef LLDB_DISABLE_PYTHON
bool SBTypeCategory::AddTypeSummary(SBTypeNameSpecifier type_name,
                                    SBTypeSummary 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->GetCommandInterpreter().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(
        lldb::RegularExpressionSP(new RegularExpression(
            llvm::StringRef::withNullAsEmpty(type_name.GetName()))),
        summary.GetSP());
  else
    m_opaque_sp->GetTypeSummariesContainer()->Add(
        ConstString(type_name.GetName()), summary.GetSP());

  return true;
}
#endif

bool SBTypeCategory::DeleteTypeSummary(SBTypeNameSpecifier 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) {
  if (!IsValid())
    return false;

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

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

  if (type_name.IsRegex())
    m_opaque_sp->GetRegexTypeFiltersContainer()->Add(
        lldb::RegularExpressionSP(new RegularExpression(
            llvm::StringRef::withNullAsEmpty(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) {
  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()));
}

#ifndef LLDB_DISABLE_PYTHON
bool SBTypeCategory::AddTypeSynthetic(SBTypeNameSpecifier type_name,
                                      SBTypeSynthetic 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->GetCommandInterpreter().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(
        lldb::RegularExpressionSP(new RegularExpression(
            llvm::StringRef::withNullAsEmpty(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) {
  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()));
}
#endif // LLDB_DISABLE_PYTHON

bool SBTypeCategory::GetDescription(lldb::SBStream &description,
                                    lldb::DescriptionLevel description_level) {
  if (!IsValid())
    return false;
  description.Printf("Category name: %s\n", GetName());
  return true;
}

lldb::SBTypeCategory &SBTypeCategory::
operator=(const lldb::SBTypeCategory &rhs) {
  if (this != &rhs) {
    m_opaque_sp = rhs.m_opaque_sp;
  }
  return *this;
}

bool SBTypeCategory::operator==(lldb::SBTypeCategory &rhs) {
  if (IsValid() == false)
    return !rhs.IsValid();

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

bool SBTypeCategory::operator!=(lldb::SBTypeCategory &rhs) {
  if (IsValid() == false)
    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);
}
