#pragma once

#include "common.h"

#include "config.h"
#include "dynamic_route_graph.h"
#include "thread_stop.h"

#include <yandex/maps/wiki/revision/snapshot.h>

#include <yandex/maps/wiki/routing/condition.h>
#include <yandex/maps/wiki/routing/element.h>
#include <yandex/maps/wiki/routing/stop.h>

#include <maps/libs/geolib/include/bounding_box.h>

#include <map>
#include <string>
#include <vector>

namespace maps {
namespace wiki {

typedef std::map<TOid, revision::ObjectRevision> IdToRevision;
typedef std::map<TOid, RouteElement> IdToRouteElement;

IdToRevision load(revision::Snapshot& snapshot, const TOIds& ids);

revision::Revisions loadSequence(revision::Snapshot& snapshot, const std::vector<TOid>& ids);

geolib3::BoundingBox findBoundingBox(const routing::Stops& stops);
geolib3::BoundingBox findBoundingBox(const RouteElements& elements);

bool isSizeLimitExceeded(const geolib3::BoundingBox& bbox, double maxSizeMeters);

std::string getElementRoleByThreadCategory(const std::string& categoryId);

TOIds getThreadElementIds(
        revision::Snapshot& snapshot,
        TOid threadId,
        const TOIds& addElementIds,
        const TOIds& removeElementIds);

TOIds findThreadElementIds(DynamicRouteGraph& graph, const routing::Stops& stops);

routing::Stops loadStops(const revision::Snapshot& snapshot, const std::vector<TOid>& stopIds);
routing::Stops toStopSequence(const IdToRevision& idToRevision, const std::vector<TOid>& stopIds);

routing::Conditions loadConditions(
        revision::Snapshot& snapshot,
        const RoutingConfig& config,
        const TOIds& elementIds);


routing::Elements toElements(
        revision::Snapshot& snapshot,
        const RoutingConfig& config,
        const IdToRevision& idToRevision);

IdToRouteElement mapIdToRouteElement(const IdToRevision& idToRevision);

std::vector<TOid> orderedThreadStopIds(const ObjectPtr& thread);

void restoreStopIds(revision::Snapshot& snapshot, ThreadStopSequence& threadStopSequence);

void restoreAttrs(revision::Snapshot& snapshot, ThreadStopSequence& threadStopSequence);

} // namespace wiki
} // namespace maps
