#pragma once

#include <maps/wikimap/mapspro/libs/controller/include/basecontroller.h>
#include <maps/wikimap/mapspro/services/editor/src/views/view_object.h>

#include <maps/wikimap/mapspro/services/editor/src/common.h>
#include "thread_stop.h"

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

#include <boost/optional.hpp>

#include <string>
#include <vector>


namespace maps {
namespace wiki {

class ObjectsQueryRouteDiff;
class ObserverCollection;

template<>
struct controller::ResultType<ObjectsQueryRouteDiff> {
    views::ViewObjects addElements;
    views::ViewObjects removeElements;
    boost::optional<geolib3::BoundingBox> elementBBox;
};

class ObjectsQueryRouteDiff : public controller::BaseController<ObjectsQueryRouteDiff> {

public:

    struct Request {
        TUid user;
        Token token;
        TBranchId branchId;

        TRevisionId revisionId;
        std::string categoryId;

        TOIds addElementIds;
        TOIds removeElementIds;

        ThreadStopSequence threadStopSequence;
        size_t fromThreadStopIdx;
        size_t toThreadStopIdx;

        size_t elementLimit;

        std::string dump() const;
        TUid userId() const { return user; }
    };

    ObjectsQueryRouteDiff(
            const ObserverCollection&,
            const Request& request,
            taskutils::TaskID asyncTaskID = 0);

    virtual ~ObjectsQueryRouteDiff() {}

    static const std::string& taskName();
    virtual std::string printRequest() const;

protected:
    virtual void control();

    Request request_;
};

} // namespace wiki
} // namespace maps
