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

#ifndef lldb_TypeCategory_h_
#define lldb_TypeCategory_h_

// C Includes
// C++ Includes
#include <initializer_list>
#include <memory>
#include <mutex>
#include <string>
#include <vector>

// Other libraries and framework includes
// Project includes
#include "lldb/lldb-enumerations.h"
#include "lldb/lldb-public.h"

#include "lldb/DataFormatters/FormatClasses.h"
#include "lldb/DataFormatters/FormattersContainer.h"

namespace lldb_private {

template <typename FormatterImpl> class FormatterContainerPair {
public:
  typedef FormattersContainer<ConstString, FormatterImpl> ExactMatchContainer;
  typedef FormattersContainer<lldb::RegularExpressionSP, FormatterImpl>
      RegexMatchContainer;

  typedef typename ExactMatchContainer::MapType ExactMatchMap;
  typedef typename RegexMatchContainer::MapType RegexMatchMap;

  typedef typename ExactMatchContainer::MapValueType MapValueType;

  typedef typename ExactMatchContainer::SharedPointer ExactMatchContainerSP;
  typedef typename RegexMatchContainer::SharedPointer RegexMatchContainerSP;

  typedef
      typename ExactMatchContainer::ForEachCallback ExactMatchForEachCallback;
  typedef
      typename RegexMatchContainer::ForEachCallback RegexMatchForEachCallback;

  FormatterContainerPair(const char *exact_name, const char *regex_name,
                         IFormatChangeListener *clist)
      : m_exact_sp(new ExactMatchContainer(std::string(exact_name), clist)),
        m_regex_sp(new RegexMatchContainer(std::string(regex_name), clist)) {}

  ~FormatterContainerPair() = default;

  ExactMatchContainerSP GetExactMatch() const { return m_exact_sp; }

  RegexMatchContainerSP GetRegexMatch() const { return m_regex_sp; }

  uint32_t GetCount() {
    return GetExactMatch()->GetCount() + GetRegexMatch()->GetCount();
  }

private:
  ExactMatchContainerSP m_exact_sp;
  RegexMatchContainerSP m_regex_sp;
};

class TypeCategoryImpl {
private:
  typedef FormatterContainerPair<TypeFormatImpl> FormatContainer;
  typedef FormatterContainerPair<TypeSummaryImpl> SummaryContainer;
  typedef FormatterContainerPair<TypeFilterImpl> FilterContainer;
  typedef FormatterContainerPair<TypeValidatorImpl> ValidatorContainer;

#ifndef LLDB_DISABLE_PYTHON
  typedef FormatterContainerPair<SyntheticChildren> SynthContainer;
#endif // LLDB_DISABLE_PYTHON

public:
  typedef uint16_t FormatCategoryItems;
  static const uint16_t ALL_ITEM_TYPES = UINT16_MAX;

  typedef FormatContainer::ExactMatchContainerSP FormatContainerSP;
  typedef FormatContainer::RegexMatchContainerSP RegexFormatContainerSP;

  typedef SummaryContainer::ExactMatchContainerSP SummaryContainerSP;
  typedef SummaryContainer::RegexMatchContainerSP RegexSummaryContainerSP;

  typedef FilterContainer::ExactMatchContainerSP FilterContainerSP;
  typedef FilterContainer::RegexMatchContainerSP RegexFilterContainerSP;
#ifndef LLDB_DISABLE_PYTHON
  typedef SynthContainer::ExactMatchContainerSP SynthContainerSP;
  typedef SynthContainer::RegexMatchContainerSP RegexSynthContainerSP;
#endif // LLDB_DISABLE_PYTHON

  typedef ValidatorContainer::ExactMatchContainerSP ValidatorContainerSP;
  typedef ValidatorContainer::RegexMatchContainerSP RegexValidatorContainerSP;

  template <typename T> class ForEachCallbacks {
  public:
    ForEachCallbacks() = default;
    ~ForEachCallbacks() = default;

    template <typename U = TypeFormatImpl>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetExact(FormatContainer::ExactMatchForEachCallback callback) {
      m_format_exact = callback;
      return *this;
    }
    template <typename U = TypeFormatImpl>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetWithRegex(FormatContainer::RegexMatchForEachCallback callback) {
      m_format_regex = callback;
      return *this;
    }

    template <typename U = TypeSummaryImpl>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetExact(SummaryContainer::ExactMatchForEachCallback callback) {
      m_summary_exact = callback;
      return *this;
    }
    template <typename U = TypeSummaryImpl>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetWithRegex(SummaryContainer::RegexMatchForEachCallback callback) {
      m_summary_regex = callback;
      return *this;
    }

    template <typename U = TypeFilterImpl>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetExact(FilterContainer::ExactMatchForEachCallback callback) {
      m_filter_exact = callback;
      return *this;
    }
    template <typename U = TypeFilterImpl>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetWithRegex(FilterContainer::RegexMatchForEachCallback callback) {
      m_filter_regex = callback;
      return *this;
    }

#ifndef LLDB_DISABLE_PYTHON
    template <typename U = SyntheticChildren>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetExact(SynthContainer::ExactMatchForEachCallback callback) {
      m_synth_exact = callback;
      return *this;
    }
    template <typename U = SyntheticChildren>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetWithRegex(SynthContainer::RegexMatchForEachCallback callback) {
      m_synth_regex = callback;
      return *this;
    }
#endif // LLDB_DISABLE_PYTHON
    template <typename U = TypeValidatorImpl>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetExact(ValidatorContainer::ExactMatchForEachCallback callback) {
      m_validator_exact = callback;
      return *this;
    }
    template <typename U = TypeValidatorImpl>
    typename std::enable_if<std::is_same<U, T>::value, ForEachCallbacks &>::type
    SetWithRegex(ValidatorContainer::RegexMatchForEachCallback callback) {
      m_validator_regex = callback;
      return *this;
    }

    FormatContainer::ExactMatchForEachCallback GetFormatExactCallback() const {
      return m_format_exact;
    }
    FormatContainer::RegexMatchForEachCallback GetFormatRegexCallback() const {
      return m_format_regex;
    }

    SummaryContainer::ExactMatchForEachCallback
    GetSummaryExactCallback() const {
      return m_summary_exact;
    }
    SummaryContainer::RegexMatchForEachCallback
    GetSummaryRegexCallback() const {
      return m_summary_regex;
    }

    FilterContainer::ExactMatchForEachCallback GetFilterExactCallback() const {
      return m_filter_exact;
    }
    FilterContainer::RegexMatchForEachCallback GetFilterRegexCallback() const {
      return m_filter_regex;
    }

#ifndef LLDB_DISABLE_PYTHON
    SynthContainer::ExactMatchForEachCallback GetSynthExactCallback() const {
      return m_synth_exact;
    }
    SynthContainer::RegexMatchForEachCallback GetSynthRegexCallback() const {
      return m_synth_regex;
    }
#endif // LLDB_DISABLE_PYTHON

    ValidatorContainer::ExactMatchForEachCallback
    GetValidatorExactCallback() const {
      return m_validator_exact;
    }
    ValidatorContainer::RegexMatchForEachCallback
    GetValidatorRegexCallback() const {
      return m_validator_regex;
    }

  private:
    FormatContainer::ExactMatchForEachCallback m_format_exact;
    FormatContainer::RegexMatchForEachCallback m_format_regex;

    SummaryContainer::ExactMatchForEachCallback m_summary_exact;
    SummaryContainer::RegexMatchForEachCallback m_summary_regex;

    FilterContainer::ExactMatchForEachCallback m_filter_exact;
    FilterContainer::RegexMatchForEachCallback m_filter_regex;

#ifndef LLDB_DISABLE_PYTHON
    SynthContainer::ExactMatchForEachCallback m_synth_exact;
    SynthContainer::RegexMatchForEachCallback m_synth_regex;
#endif // LLDB_DISABLE_PYTHON

    ValidatorContainer::ExactMatchForEachCallback m_validator_exact;
    ValidatorContainer::RegexMatchForEachCallback m_validator_regex;
  };

  TypeCategoryImpl(IFormatChangeListener *clist, ConstString name,
                   std::initializer_list<lldb::LanguageType> langs = {});

  template <typename T> void ForEach(const ForEachCallbacks<T> &foreach) {
    GetTypeFormatsContainer()->ForEach(foreach.GetFormatExactCallback());
    GetRegexTypeFormatsContainer()->ForEach(foreach.GetFormatRegexCallback());

    GetTypeSummariesContainer()->ForEach(foreach.GetSummaryExactCallback());
    GetRegexTypeSummariesContainer()->ForEach(
        foreach.GetSummaryRegexCallback());

    GetTypeFiltersContainer()->ForEach(foreach.GetFilterExactCallback());
    GetRegexTypeFiltersContainer()->ForEach(foreach.GetFilterRegexCallback());

#ifndef LLDB_DISABLE_PYTHON
    GetTypeSyntheticsContainer()->ForEach(foreach.GetSynthExactCallback());
    GetRegexTypeSyntheticsContainer()->ForEach(foreach.GetSynthRegexCallback());
#endif // LLDB_DISABLE_PYTHON

    GetTypeValidatorsContainer()->ForEach(foreach.GetValidatorExactCallback());
    GetRegexTypeValidatorsContainer()->ForEach(
        foreach.GetValidatorRegexCallback());
  }

  FormatContainerSP GetTypeFormatsContainer() {
    return m_format_cont.GetExactMatch();
  }

  RegexFormatContainerSP GetRegexTypeFormatsContainer() {
    return m_format_cont.GetRegexMatch();
  }

  FormatContainer &GetFormatContainer() { return m_format_cont; }

  SummaryContainerSP GetTypeSummariesContainer() {
    return m_summary_cont.GetExactMatch();
  }

  RegexSummaryContainerSP GetRegexTypeSummariesContainer() {
    return m_summary_cont.GetRegexMatch();
  }

  SummaryContainer &GetSummaryContainer() { return m_summary_cont; }

  FilterContainerSP GetTypeFiltersContainer() {
    return m_filter_cont.GetExactMatch();
  }

  RegexFilterContainerSP GetRegexTypeFiltersContainer() {
    return m_filter_cont.GetRegexMatch();
  }

  FilterContainer &GetFilterContainer() { return m_filter_cont; }

  FormatContainer::MapValueType
  GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp);

  SummaryContainer::MapValueType
  GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp);

  FilterContainer::MapValueType
  GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp);

#ifndef LLDB_DISABLE_PYTHON
  SynthContainer::MapValueType
  GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp);
#endif

  ValidatorContainer::MapValueType
  GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp);

  lldb::TypeNameSpecifierImplSP
  GetTypeNameSpecifierForFormatAtIndex(size_t index);

  lldb::TypeNameSpecifierImplSP
  GetTypeNameSpecifierForSummaryAtIndex(size_t index);

  FormatContainer::MapValueType GetFormatAtIndex(size_t index);

  SummaryContainer::MapValueType GetSummaryAtIndex(size_t index);

  FilterContainer::MapValueType GetFilterAtIndex(size_t index);

  lldb::TypeNameSpecifierImplSP
  GetTypeNameSpecifierForFilterAtIndex(size_t index);

#ifndef LLDB_DISABLE_PYTHON
  SynthContainerSP GetTypeSyntheticsContainer() {
    return m_synth_cont.GetExactMatch();
  }

  RegexSynthContainerSP GetRegexTypeSyntheticsContainer() {
    return m_synth_cont.GetRegexMatch();
  }

  SynthContainer &GetSyntheticsContainer() { return m_synth_cont; }

  SynthContainer::MapValueType GetSyntheticAtIndex(size_t index);

  lldb::TypeNameSpecifierImplSP
  GetTypeNameSpecifierForSyntheticAtIndex(size_t index);
#endif // LLDB_DISABLE_PYTHON

  ValidatorContainerSP GetTypeValidatorsContainer() {
    return m_validator_cont.GetExactMatch();
  }

  RegexValidatorContainerSP GetRegexTypeValidatorsContainer() {
    return m_validator_cont.GetRegexMatch();
  }

  ValidatorContainer::MapValueType GetValidatorAtIndex(size_t index);

  lldb::TypeNameSpecifierImplSP
  GetTypeNameSpecifierForValidatorAtIndex(size_t index);

  bool IsEnabled() const { return m_enabled; }

  uint32_t GetEnabledPosition() {
    if (m_enabled == false)
      return UINT32_MAX;
    else
      return m_enabled_position;
  }

  bool Get(ValueObject &valobj, const FormattersMatchVector &candidates,
           lldb::TypeFormatImplSP &entry, uint32_t *reason = nullptr);

  bool Get(ValueObject &valobj, const FormattersMatchVector &candidates,
           lldb::TypeSummaryImplSP &entry, uint32_t *reason = nullptr);

  bool Get(ValueObject &valobj, const FormattersMatchVector &candidates,
           lldb::SyntheticChildrenSP &entry, uint32_t *reason = nullptr);

  bool Get(ValueObject &valobj, const FormattersMatchVector &candidates,
           lldb::TypeValidatorImplSP &entry, uint32_t *reason = nullptr);

  void Clear(FormatCategoryItems items = ALL_ITEM_TYPES);

  bool Delete(ConstString name, FormatCategoryItems items = ALL_ITEM_TYPES);

  uint32_t GetCount(FormatCategoryItems items = ALL_ITEM_TYPES);

  const char *GetName() { return m_name.GetCString(); }

  size_t GetNumLanguages();

  lldb::LanguageType GetLanguageAtIndex(size_t idx);

  void AddLanguage(lldb::LanguageType lang);

  bool HasLanguage(lldb::LanguageType lang);

  std::string GetDescription();

  bool AnyMatches(ConstString type_name,
                  FormatCategoryItems items = ALL_ITEM_TYPES,
                  bool only_enabled = true,
                  const char **matching_category = nullptr,
                  FormatCategoryItems *matching_type = nullptr);

  typedef std::shared_ptr<TypeCategoryImpl> SharedPointer;

private:
  FormatContainer m_format_cont;
  SummaryContainer m_summary_cont;
  FilterContainer m_filter_cont;
#ifndef LLDB_DISABLE_PYTHON
  SynthContainer m_synth_cont;
#endif // LLDB_DISABLE_PYTHON
  ValidatorContainer m_validator_cont;

  bool m_enabled;

  IFormatChangeListener *m_change_listener;

  std::recursive_mutex m_mutex;

  ConstString m_name;

  std::vector<lldb::LanguageType> m_languages;

  uint32_t m_enabled_position;

  void Enable(bool value, uint32_t position);

  void Disable() { Enable(false, UINT32_MAX); }

  bool IsApplicable(ValueObject &valobj);

  uint32_t GetLastEnabledPosition() { return m_enabled_position; }

  void SetEnabledPosition(uint32_t p) { m_enabled_position = p; }

  friend class FormatManager;
  friend class LanguageCategory;
  friend class TypeCategoryMap;

  friend class FormattersContainer<ConstString, TypeFormatImpl>;
  friend class FormattersContainer<lldb::RegularExpressionSP, TypeFormatImpl>;

  friend class FormattersContainer<ConstString, TypeSummaryImpl>;
  friend class FormattersContainer<lldb::RegularExpressionSP, TypeSummaryImpl>;

  friend class FormattersContainer<ConstString, TypeFilterImpl>;
  friend class FormattersContainer<lldb::RegularExpressionSP, TypeFilterImpl>;

#ifndef LLDB_DISABLE_PYTHON
  friend class FormattersContainer<ConstString, ScriptedSyntheticChildren>;
  friend class FormattersContainer<lldb::RegularExpressionSP,
                                   ScriptedSyntheticChildren>;
#endif // LLDB_DISABLE_PYTHON

  friend class FormattersContainer<ConstString, TypeValidatorImpl>;
  friend class FormattersContainer<lldb::RegularExpressionSP,
                                   TypeValidatorImpl>;
};

} // namespace lldb_private

#endif // lldb_TypeCategory_h_
