// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/backoff_entry.h"

#include <algorithm>
#include <cmath>

#include "base/logging.h"
#include "base/rand_util.h"

namespace net {

BackoffEntry::BackoffEntry(const BackoffEntry::Policy* const policy)
    : failure_count_(0),
      policy_(policy) {
  DCHECK(policy_);

  // Can't use GetTimeNow() as it's virtual.
  exponential_backoff_release_time_ = base::TimeTicks::Now();
}

BackoffEntry::~BackoffEntry() {
  // TODO(joi): Remove this once our clients (e.g. URLRequestThrottlerManager)
  // always destroy from the I/O thread.
  DetachFromThread();
}

void BackoffEntry::InformOfRequest(bool succeeded) {
  if (!succeeded) {
    ++failure_count_;
    exponential_backoff_release_time_ = CalculateReleaseTime();
  } else {
    // We slowly decay the number of times delayed instead of resetting it to 0
    // in order to stay stable if we receive successes interleaved between lots
    // of failures.
    //
    // TODO(joi): Revisit this; it might be most correct to go to zero
    // but have a way to go back to "old error count +1" if there is
    // another error soon after.
    if (failure_count_ > 0)
      --failure_count_;

    // The reason why we are not just cutting the release time to GetTimeNow()
    // is on the one hand, it would unset a release time set by
    // SetCustomReleaseTime and on the other we would like to push every
    // request up to our "horizon" when dealing with multiple in-flight
    // requests. Ex: If we send three requests and we receive 2 failures and
    // 1 success. The success that follows those failures will not reset the
    // release time, further requests will then need to wait the delay caused
    // by the 2 failures.
    exponential_backoff_release_time_ = std::max(
        GetTimeNow(), exponential_backoff_release_time_);
  }
}

bool BackoffEntry::ShouldRejectRequest() const {
  return exponential_backoff_release_time_ > GetTimeNow();
}

base::TimeTicks BackoffEntry::GetReleaseTime() const {
  return exponential_backoff_release_time_;
}

void BackoffEntry::SetCustomReleaseTime(const base::TimeTicks& release_time) {
  exponential_backoff_release_time_ = release_time;
}

bool BackoffEntry::CanDiscard() const {
  if (policy_->entry_lifetime_ms == -1)
    return false;

  base::TimeTicks now = GetTimeNow();

  int64 unused_since_ms =
      (now - exponential_backoff_release_time_).InMilliseconds();

  // Release time is further than now, we are managing it.
  if (unused_since_ms < 0)
    return false;

  if (failure_count_ > 0) {
    // Need to keep track of failures until maximum back-off period
    // has passed (since further failures can add to back-off).
    return unused_since_ms >= std::max(policy_->maximum_backoff_ms,
                                       policy_->entry_lifetime_ms);
  }

  // Otherwise, consider the entry is outdated if it hasn't been used for the
  // specified lifetime period.
  return unused_since_ms >= policy_->entry_lifetime_ms;
}

base::TimeTicks BackoffEntry::GetTimeNow() const {
  return base::TimeTicks::Now();
}

base::TimeTicks BackoffEntry::CalculateReleaseTime() const {
  int effective_failure_count =
      std::max(0, failure_count_ - policy_->num_errors_to_ignore);
  if (effective_failure_count == 0) {
    // Never reduce previously set release horizon, e.g. due to Retry-After
    // header.
    return std::max(GetTimeNow(), exponential_backoff_release_time_);
  }

  // The delay is calculated with this formula:
  // delay = initial_backoff * multiply_factor^(
  //     effective_failure_count - 1) * Uniform(1 - jitter_factor, 1]
  double delay = policy_->initial_backoff_ms;
  delay *= pow(policy_->multiply_factor, effective_failure_count - 1);
  delay -= base::RandDouble() * policy_->jitter_factor * delay;

  // Ensure that we do not exceed maximum delay.
  int64 delay_int = static_cast<int64>(delay + 0.5);
  delay_int = std::min(delay_int,
                       static_cast<int64>(policy_->maximum_backoff_ms));

  // Never reduce previously set release horizon, e.g. due to Retry-After
  // header.
  return std::max(GetTimeNow() + base::TimeDelta::FromMilliseconds(delay_int),
                  exponential_backoff_release_time_);
}

}  // namespace net
