#pragma once

#include <yandex/maps/wiki/topo/cache.h>

namespace maps {
namespace wiki {
namespace topo {

namespace index {

class SpatialIndex;

}

class Storage;
class Graph;
class Editor;

class CacheImpl {
public:
    CacheImpl(Storage& storage, double tolerance,
        std::unique_ptr<index::SpatialIndex> index);

    IncidencesByNodeMap incidencesByNodes(const NodeIDSet& nodeIds);
    IncidencesByEdgeMap incidencesByEdges(const EdgeIDSet& edgeIds);

    boost::optional<Circuit> circuit(const EdgeIDSet& edgeIds, bool withNodes);

    void loadObjects(const geolib3::BoundingBox& bbox);
    void loadObjects(const geolib3::Point2& center,
        double width, double height);
    void loadObjects(const geolib3::Polyline2& polyline,
        double withinDistance);

    void loadByNodes(const NodeIDSet& nodeIds);
    void loadByEdges(const EdgeIDSet& edgeIds);

    void loadEdgeFaces(const EdgeIDSet& edgeIds);

    // получить редактор, ассоциированный с кэшем
    std::unique_ptr<Editor> editor();
    std::unique_ptr<FaceValidator> faceValidator();

    // источник, на котором основан кэш
    Storage& storage() { return storage_; }
    const Storage& storage() const { return storage_; }

    // непосредственно хранилище объектов, индексированное
    Graph& graph() { return *graph_; }
    const Graph& graph() const { return *graph_; }

private:
    Storage& storage_;
    std::unique_ptr<Graph> graph_;
};

} // namespace topo
} // namespace wiki
} // namespace maps
