#pragma once

#include "bbox_context.h"
#include "categories_holder.h"

#include <maps/wikimap/mapspro/services/editor/src/common.h>
#include <maps/wikimap/mapspro/services/editor/src/execution_state.h>
#include <maps/wikimap/mapspro/services/editor/src/revision_meta/common.h>

#include <atomic>
#include <mutex>

namespace maps {
namespace wiki {

const size_t COMMIT_RANGE_BATCH_SIZE = 1000;

struct ComputeBBoxesParams
{
    BBoxUpdateAction action;
    TBranchId branchId;
    TCommitId startCommitId;
    TCommitId lastCommitId;
    TCommitIds customCommitIds;
    size_t commitRangeBatchSize;
    StringSet categoryIds;
    size_t threadPoolSize;
    ExecutionStatePtr executionState;
};

class ComputeBBoxTask
{
public:
    explicit ComputeBBoxTask(const ComputeBBoxesParams& params);

    void exec(Transaction& mainTxn);

private:
    void loadComplexObjectIds(
        const BBoxContext& context,
        size_t threadPoolSize);
    void computeHistoryForCommitRange(
        Transaction& mainTxn,
        TCommitId startCommitId,
        TCommitId endCommitId);
    void computeHistoryForComplexObjects(
        TOIds complexObjectIds,
        std::string topLevelCategoryId,
        BBoxContext context);

    TOIds prepareObjectIdsForUpdateViews() const;
    void updateViews(Transaction& mainTxn) const;
    void updateViewForObjects(TOIds objectIds) const;
    void preloadNonCachedObjects(ObjectsCache& cache) const;

    ComputeBBoxesParams params_;
    CategoriesHolder categoriesHolder_;

    std::atomic<bool> failed_;

    std::map<std::string, TOIds> complexObjectIdsByCategory_;

    std::mutex globalGeomCacheMutex_;
    std::unordered_map<TOid, Geom> globalGeomCache_;
};

} // namespace wiki
} // namespace maps
