#pragma once

#include <maps/wikimap/mapspro/libs/taskutils/include/common.h>
#include <maps/wikimap/mapspro/libs/taskutils/include/task.h>
#include <maps/wikimap/mapspro/libs/taskutils/include/taskresult.h>

#include <memory>
#include <vector>

namespace maps::wiki::taskutils {

class TaskInfo;
class Token;
class TaskManagerImpl;

typedef std::vector<Token> Tokens;

class TaskManager {
public:
    enum FindPolicy
    {
        ActiveAndDone,
        Active
    };
    explicit TaskManager(const std::string& tokenSecretWord, const std::string& dbSchema = "");
    virtual ~TaskManager();

    const std::string& tokenSecretWord() const;

    /// check expires (token and db) and load fields: status, result, error_message
    TaskResult load(Transaction& work, const Token& token) const;

    /// check expires (db only) and load fields: status, result, error_message
    TaskResult load(Transaction& work, TaskID id) const;

    /// the tasks creator
    Task create(
        Transaction& work, const TaskInfo& taskInfo,
        TUid uid, size_t deadlineTimeout) const;

    /// cancel any task by id with 'created' and 'started' status
    bool cancel(Transaction& work, TaskID id) const;

    /// terminate all known tasks with 'created' and 'started' status, and forgot them
    void terminateAll(Transaction& work) const;

    /// remove expired tasks and keep some historical data
    size_t removeExpired(Transaction& work, size_t keepTime) const;

    Tokens findTasksTokens(Transaction& work,
        const std::string& metadataPatternJson, TUid createdBy, FindPolicy findPolicy) const;

private:
    TaskManager(const TaskManager&) = delete;
    TaskManager& operator = (const TaskManager&) = delete;

    std::unique_ptr<TaskManagerImpl> impl_;
};

} // namespace maps::wiki::taskutils
