#pragma once

#include "inmemory_objects_collection.h"
#include <maps/wikimap/mapspro/libs/validator/common/categories_list.h>

#include <functional>
#include <unordered_map>

namespace maps {
namespace wiki {
namespace validator {

template<class Category>
struct CategoryObjectsCollection
{
    typedef InMemoryObjectsCollection<Category> type;
};

template<typename TypeList> struct MakeCollectionsTuple;

template<typename... Categories>
struct MakeCollectionsTuple<TypeList<Categories...>>
{
    struct type : public CategoryObjectsCollection<Categories>::type... { };
};

typedef typename MakeCollectionsTuple<CategoriesList>::type ObjectsCollectionsTuple;

template<class Category>
const typename CategoryObjectsCollection<Category>::type&
castToCollection(const ObjectsCollectionsTuple& tuple)
{
    return static_cast<
        const typename CategoryObjectsCollection<Category>::type&
        >(tuple);
}

template<class Category>
typename CategoryObjectsCollection<Category>::type&
castToCollection(ObjectsCollectionsTuple& tuple)
{
    return static_cast<
        typename CategoryObjectsCollection<Category>::type&
        >(tuple);
}

typedef std::unordered_map<TCategoryId, std::reference_wrapper<ObjectsCollectionBase>>
    ObjectsCollectionsMap;

ObjectsCollectionsMap collectionsTupleToCollectionsMap(ObjectsCollectionsTuple&);

} // namespace validator
} // namespace wiki
} // namespace maps
