// Copyright (c) 2012 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 <limits>

#include "base/logging.h"
#include "base/numerics/safe_math.h"
#include "base/rand_util.h"
#include "base/time/tick_clock.h"

#include "starboard/client_porting/cwrappers/pow_wrapper.h"

#if defined(STARBOARD)
#include "starboard/types.h"
#endif

namespace net {

BackoffEntry::BackoffEntry(const BackoffEntry::Policy* policy)
    : BackoffEntry(policy, nullptr) {}

BackoffEntry::BackoffEntry(const BackoffEntry::Policy* policy,
                           const base::TickClock* clock)
    : policy_(policy), clock_(clock) {
  DCHECK(policy_);
  Reset();
}

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

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.  Note that in
    // the normal case, the calculated release time (in the next
    // statement) will be in the past once the method returns.
    if (failure_count_ > 0)
      --failure_count_;

    // The reason why we are not just cutting the release time to
    // GetTimeTicksNow() 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.
    base::TimeDelta delay;
    if (policy_->always_use_initial_delay)
      delay = base::TimeDelta::FromMilliseconds(policy_->initial_delay_ms);
    exponential_backoff_release_time_ =
        std::max(GetTimeTicksNow() + delay, exponential_backoff_release_time_);
  }
}

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

base::TimeDelta BackoffEntry::GetTimeUntilRelease() const {
  base::TimeTicks now = GetTimeTicksNow();
  if (exponential_backoff_release_time_ <= now)
    return base::TimeDelta();
  return exponential_backoff_release_time_ - now;
}

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 = GetTimeTicksNow();

  int64_t 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;
}

void BackoffEntry::Reset() {
  failure_count_ = 0;
  // For legacy reasons, we reset exponential_backoff_release_time_ to the
  // uninitialized state. It would also be reasonable to reset it to
  // GetTimeTicksNow(). The effects are the same, i.e. ShouldRejectRequest()
  // will return false right after Reset().
  exponential_backoff_release_time_ = base::TimeTicks();
}

base::TimeTicks BackoffEntry::GetTimeTicksNow() const {
  return clock_ ? clock_->NowTicks() : base::TimeTicks::Now();
}

base::TimeTicks BackoffEntry::CalculateReleaseTime() const {
  int effective_failure_count =
      std::max(0, failure_count_ - policy_->num_errors_to_ignore);

  // If always_use_initial_delay is true, it's equivalent to
  // the effective_failure_count always being one greater than when it's false.
  if (policy_->always_use_initial_delay)
    ++effective_failure_count;

  if (effective_failure_count == 0) {
    // Never reduce previously set release horizon, e.g. due to Retry-After
    // header.
    return std::max(GetTimeTicksNow(), 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]
  // Note: if the failure count is too high, |delay_ms| will become infinity
  // after the exponential calculation, and then NaN after the jitter is
  // accounted for. Both cases are handled by using CheckedNumeric<int64_t> to
  // perform the conversion to integers.
  double delay_ms = policy_->initial_delay_ms;
  delay_ms *= pow(policy_->multiply_factor, effective_failure_count - 1);
  delay_ms -= base::RandDouble() * policy_->jitter_factor * delay_ms;

  // Do overflow checking in microseconds, the internal unit of TimeTicks.
  base::internal::CheckedNumeric<int64_t> backoff_duration_us = delay_ms + 0.5;
  backoff_duration_us *= base::Time::kMicrosecondsPerMillisecond;
  base::TimeDelta backoff_duration = base::TimeDelta::FromMicroseconds(
      backoff_duration_us.ValueOrDefault(std::numeric_limits<int64_t>::max()));
  base::TimeTicks release_time = BackoffDurationToReleaseTime(backoff_duration);

  // Never reduce previously set release horizon, e.g. due to Retry-After
  // header.
  return std::max(release_time, exponential_backoff_release_time_);
}

base::TimeTicks BackoffEntry::BackoffDurationToReleaseTime(
    base::TimeDelta backoff_duration) const {
  const int64_t kTimeTicksNowUs =
      (GetTimeTicksNow() - base::TimeTicks()).InMicroseconds();
  // Do overflow checking in microseconds, the internal unit of TimeTicks.
  base::internal::CheckedNumeric<int64_t> calculated_release_time_us =
      backoff_duration.InMicroseconds();
  calculated_release_time_us += kTimeTicksNowUs;

  base::internal::CheckedNumeric<int64_t> maximum_release_time_us =
      std::numeric_limits<int64_t>::max();
  if (policy_->maximum_backoff_ms >= 0) {
    maximum_release_time_us = policy_->maximum_backoff_ms;
    maximum_release_time_us *= base::Time::kMicrosecondsPerMillisecond;
    maximum_release_time_us += kTimeTicksNowUs;
  }

  // Decide between maximum release time and calculated release time, accounting
  // for overflow with both.
  int64_t release_time_us = std::min(calculated_release_time_us.ValueOrDefault(
                                         std::numeric_limits<int64_t>::max()),
                                     maximum_release_time_us.ValueOrDefault(
                                         std::numeric_limits<int64_t>::max()));

  return base::TimeTicks() + base::TimeDelta::FromMicroseconds(release_time_us);
}

}  // namespace net
