//===-- TypeCategoryMap.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_TypeCategoryMap_h_
#define lldb_TypeCategoryMap_h_

// C Includes
// C++ Includes
#include <functional>
#include <list>
#include <map>
#include <mutex>

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

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

namespace lldb_private {
class TypeCategoryMap {
private:
  typedef ConstString KeyType;
  typedef TypeCategoryImpl ValueType;
  typedef ValueType::SharedPointer ValueSP;
  typedef std::list<lldb::TypeCategoryImplSP> ActiveCategoriesList;
  typedef ActiveCategoriesList::iterator ActiveCategoriesIterator;

public:
  typedef std::map<KeyType, ValueSP> MapType;
  typedef MapType::iterator MapIterator;
  typedef std::function<bool(const ValueSP &)> ForEachCallback;

  typedef uint32_t Position;

  static const Position First = 0;
  static const Position Default = 1;
  static const Position Last = UINT32_MAX;

  TypeCategoryMap(IFormatChangeListener *lst);

  void Add(KeyType name, const ValueSP &entry);

  bool Delete(KeyType name);

  bool Enable(KeyType category_name, Position pos = Default);

  bool Disable(KeyType category_name);

  bool Enable(ValueSP category, Position pos = Default);

  bool Disable(ValueSP category);

  void EnableAllCategories();

  void DisableAllCategories();

  void Clear();

  bool Get(KeyType name, ValueSP &entry);

  bool Get(uint32_t pos, ValueSP &entry);

  void ForEach(ForEachCallback callback);

  lldb::TypeCategoryImplSP GetAtIndex(uint32_t);

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

  uint32_t GetCount() { return m_map.size(); }

  lldb::TypeFormatImplSP GetFormat(FormattersMatchData &match_data);

  lldb::TypeSummaryImplSP GetSummaryFormat(FormattersMatchData &match_data);

#ifndef LLDB_DISABLE_PYTHON
  lldb::SyntheticChildrenSP
  GetSyntheticChildren(FormattersMatchData &match_data);
#endif

  lldb::TypeValidatorImplSP GetValidator(FormattersMatchData &match_data);

private:
  class delete_matching_categories {
    lldb::TypeCategoryImplSP ptr;

  public:
    delete_matching_categories(lldb::TypeCategoryImplSP p) : ptr(p) {}

    bool operator()(const lldb::TypeCategoryImplSP &other) {
      return ptr.get() == other.get();
    }
  };

  std::recursive_mutex m_map_mutex;
  IFormatChangeListener *listener;

  MapType m_map;
  ActiveCategoriesList m_active_categories;

  MapType &map() { return m_map; }

  ActiveCategoriesList &active_list() { return m_active_categories; }

  std::recursive_mutex &mutex() { return m_map_mutex; }

  friend class FormattersContainer<KeyType, ValueType>;
  friend class FormatManager;
};
} // namespace lldb_private

#endif // lldb_TypeCategoryMap_h_
