#include <maps/wikimap/mapspro/libs/common/include/yandex/maps/wiki/common/retry_duration.h>

namespace maps::wiki::common {

namespace {
std::chrono::seconds g_defaultDuration = std::chrono::hours(3);
std::chrono::milliseconds g_defaultSleepTime = std::chrono::minutes(1);
} // namespace

RetryDurationPolicy::RetryDurationPolicy()
    : duration_(g_defaultDuration)
    , sleepTime_(g_defaultSleepTime)
{}

void RetryDurationPolicy::setDefaultDuration(std::chrono::seconds duration)
{
    REQUIRE(duration.count() > 0, "Empty default duration");
    g_defaultDuration = duration;
}

void RetryDurationPolicy::setDefaultSleepTime(std::chrono::milliseconds sleepTime)
{
    REQUIRE(sleepTime.count() > 0, "Empty default sleep time");
    g_defaultSleepTime = sleepTime;
}

size_t RetryDurationPolicy::maxTries() const
{
    auto sleepTimeMs = sleepTime_.count();
    auto durationMs = std::chrono::milliseconds(duration_).count();

    return (durationMs + sleepTimeMs - 1) / sleepTimeMs;
}

RetryDurationPolicy& RetryDurationPolicy::setDuration(std::chrono::seconds duration)
{
    REQUIRE(duration.count() > 0, "Empty duration");
    duration_ = duration;
    return *this;
}

RetryDurationPolicy& RetryDurationPolicy::setSleepTime(std::chrono::milliseconds sleepTime)
{
    REQUIRE(sleepTime.count() > 0, "Empty sleep time");
    sleepTime_ = sleepTime;
    return *this;
}

void RetryDurationPolicy::checkDeadline(
    std::chrono::steady_clock::time_point deadline) const
{
    if (std::chrono::steady_clock::now() >= deadline) {
        throw RetryDurationExpired() <<
            "Duration " << duration_.count() << "s expired";
    }
}

} // namespace maps::wiki::common
