#include <maps/wikimap/mapspro/services/mrc/libs/common/include/algorithm/retry.h>

#include <cstddef>
#include <chrono>

namespace maps {
namespace mrc {
namespace common {

namespace {

constexpr std::chrono::milliseconds DEFAULT_INITIAL_TIMEOUT{0};
constexpr size_t DEFAULT_TIMEOUT_BACKOFF = 1;
constexpr size_t DEFAULT_RETRY_NUMBER = 1;

} //anonymous namespace

class RetryPolicy::Impl
{
public:
    std::chrono::milliseconds initialTimeout;
    size_t timeoutBackoff;
    size_t maxAttempts;
};

RetryPolicy::RetryPolicy()
    : impl_(new Impl{
        DEFAULT_INITIAL_TIMEOUT,
        DEFAULT_TIMEOUT_BACKOFF,
        DEFAULT_RETRY_NUMBER
    })
{
}

RetryPolicy::RetryPolicy(const RetryPolicy& toCopy)
{
    *this = toCopy;
}

RetryPolicy&
RetryPolicy::operator= (const RetryPolicy& toCopy)
{
    if (this != &toCopy) {
        impl_.reset(new Impl(*toCopy.impl_));
    }
    return *this;
}

RetryPolicy::~RetryPolicy() = default;

std::chrono::milliseconds RetryPolicy::initialTimeout() const
{
    return impl_->initialTimeout;
}

RetryPolicy& RetryPolicy::setInitialTimeout(std::chrono::milliseconds timeout)
{
    impl_->initialTimeout = timeout;
    return *this;
}

size_t RetryPolicy::timeoutBackoff() const
{
    return impl_->timeoutBackoff;
}

RetryPolicy& RetryPolicy::setTimeoutBackoff(size_t backoff)
{
    impl_->timeoutBackoff = backoff;
    return *this;
}

size_t RetryPolicy::maxAttempts() const
{
    return impl_->maxAttempts;
}

RetryPolicy& RetryPolicy::setMaxAttempts(size_t attempts)
{
    impl_->maxAttempts = attempts;
    return *this;
}

} //namespace common
} //namespace mrc
} //namespace maps
