#pragma once

#include <maps/libs/concurrent/include/lru_cache.h>
#include <maps/libs/pgpool/include/pgpool3.h>
#include <maps/wikimap/mapspro/libs/acl/include/check_context.h>
#include <maps/wikimap/mapspro/libs/acl/include/common.h>

namespace maps::wiki::acl_utils {

using SteadyTimePoint = std::chrono::time_point<std::chrono::steady_clock>;

struct TimedCheckContext {
    acl::CheckContext ctx;
    SteadyTimePoint created;
};

/**
 * @brief Class for checking user permissions in wiki-acl
 *
 */
class CachingAclChecker {
public:
    CachingAclChecker(pgpool3::Pool& pgPool,
                      size_t maxCacheSize,
                      std::chrono::seconds expirationPeriod)
        : pgPool_(pgPool)
        , cache_(maxCacheSize)
        , expirationPeriod_(expirationPeriod)
    { }

    bool userHasPermission(acl::UID uid, const std::string& permission);
    bool userHasPartOfPermission(acl::UID uid, const std::string& permission);
    void checkPermission(acl::UID uid, const std::string& permission);

private:
    std::shared_ptr<TimedCheckContext> getCheckContext(acl::UID uid);

    pgpool3::Pool& pgPool_;
    concurrent::LruCache<acl::UID, TimedCheckContext> cache_;
    std::chrono::seconds expirationPeriod_;
};

} // namespace maps::wiki::acl_utils
