// Copyright 2016 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/network_throttle_manager_impl.h"

#include "base/logging.h"
#include "base/stl_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/default_tick_clock.h"

namespace net {

const size_t NetworkThrottleManagerImpl::kActiveRequestThrottlingLimit = 2;
const int NetworkThrottleManagerImpl::kMedianLifetimeMultiple = 5;

// Initial estimate based on the median in the
// Net.RequestTime2.Success histogram, excluding cached results by eye.
const int NetworkThrottleManagerImpl::kInitialMedianInMs = 400;

// Set timers slightly further into the future than they need to be set, so
// that the algorithm isn't vulnerable to timer round off errors triggering
// the callback before the throttle would be considered aged out of the set.
// Set to 17 to hanlde systems with |!base::TimeTicks::IsHighResolution()|.
// Note that even if the timer goes off before it should, all that should cost
// is a second task; this class does not rely on timer accuracy for its
// correctness.
const int kTimerFudgeInMs = 17;

class NetworkThrottleManagerImpl::ThrottleImpl
    : public NetworkThrottleManager::Throttle {
 public:
  // Allowed state transitions are BLOCKED -> OUTSTANDING -> AGED.
  // Throttles may be created in the BLOCKED or OUTSTANDING states.
  enum class State {
    // Not allowed to proceed by manager.
    BLOCKED,

    // Allowed to proceed, counts as an "outstanding" request for
    // manager accounting purposes.
    OUTSTANDING,

    // Old enough to not count as "outstanding" anymore for
    // manager accounting purposes.
    AGED
  };

  using ThrottleListQueuePointer =
      NetworkThrottleManagerImpl::ThrottleList::iterator;

  // Caller must arrange that |*delegate| and |*manager| outlive
  // the ThrottleImpl class.
  ThrottleImpl(bool blocked,
               RequestPriority priority,
               ThrottleDelegate* delegate,
               NetworkThrottleManagerImpl* manager,
               ThrottleListQueuePointer queue_pointer);

  ~ThrottleImpl() override;

  // Throttle:
  bool IsBlocked() const override;
  RequestPriority Priority() const override;
  void SetPriority(RequestPriority priority) override;

  State state() const { return state_; }

  ThrottleListQueuePointer queue_pointer() const { return queue_pointer_; }
  void set_queue_pointer(const ThrottleListQueuePointer& pointer) {
    if (state_ != State::AGED)
      DCHECK_EQ(this, *pointer);
    queue_pointer_ = pointer;
  }

  void set_start_time(base::TimeTicks start_time) { start_time_ = start_time; }
  base::TimeTicks start_time() const { return start_time_; }

  // Change the throttle's state to AGED.  The previous
  // state must be OUTSTANDING.
  void SetAged();

  // Note that this call calls the delegate, and hence may result in
  // re-entrant calls into the manager or ThrottleImpl.  The manager should
  // not rely on any state other than its own existence being persistent
  // across this call.
  void NotifyUnblocked();

 private:
  State state_;
  RequestPriority priority_;
  ThrottleDelegate* const delegate_;
  NetworkThrottleManagerImpl* const manager_;

  base::TimeTicks start_time_;

  // To allow deletion from the blocked queue (when the throttle is in the
  // blocked queue).
  ThrottleListQueuePointer queue_pointer_;

  DISALLOW_COPY_AND_ASSIGN(ThrottleImpl);
};

NetworkThrottleManagerImpl::ThrottleImpl::ThrottleImpl(
    bool blocked,
    RequestPriority priority,
    NetworkThrottleManager::ThrottleDelegate* delegate,
    NetworkThrottleManagerImpl* manager,
    ThrottleListQueuePointer queue_pointer)
    : state_(blocked ? State::BLOCKED : State::OUTSTANDING),
      priority_(priority),
      delegate_(delegate),
      manager_(manager),
      queue_pointer_(queue_pointer) {
  DCHECK(delegate);
  if (!blocked)
    start_time_ = manager->tick_clock_->NowTicks();
}

NetworkThrottleManagerImpl::ThrottleImpl::~ThrottleImpl() {
  manager_->OnThrottleDestroyed(this);
}

bool NetworkThrottleManagerImpl::ThrottleImpl::IsBlocked() const {
  return state_ == State::BLOCKED;
}

RequestPriority NetworkThrottleManagerImpl::ThrottleImpl::Priority() const {
  return priority_;
}

void NetworkThrottleManagerImpl::ThrottleImpl::SetPriority(
    RequestPriority new_priority) {
  RequestPriority old_priority(priority_);
  if (old_priority == new_priority)
    return;
  priority_ = new_priority;
  manager_->OnThrottlePriorityChanged(this, old_priority, new_priority);
}

void NetworkThrottleManagerImpl::ThrottleImpl::SetAged() {
  DCHECK_EQ(State::OUTSTANDING, state_);
  state_ = State::AGED;
}

void NetworkThrottleManagerImpl::ThrottleImpl::NotifyUnblocked() {
  // This method should only be called once, and only if the
  // current state is blocked.
  DCHECK_EQ(State::BLOCKED, state_);
  state_ = State::OUTSTANDING;
  delegate_->OnThrottleUnblocked(this);
}

NetworkThrottleManagerImpl::NetworkThrottleManagerImpl()
    : lifetime_median_estimate_(PercentileEstimator::kMedianPercentile,
                                kInitialMedianInMs),
      outstanding_recomputation_timer_(std::make_unique<base::OneShotTimer>()),
      tick_clock_(base::DefaultTickClock::GetInstance()),
      weak_ptr_factory_(this) {}

NetworkThrottleManagerImpl::~NetworkThrottleManagerImpl() = default;

std::unique_ptr<NetworkThrottleManager::Throttle>
NetworkThrottleManagerImpl::CreateThrottle(
    NetworkThrottleManager::ThrottleDelegate* delegate,
    RequestPriority priority,
    bool ignore_limits) {
  bool blocked =
      (!ignore_limits && priority == THROTTLED &&
       outstanding_throttles_.size() >= kActiveRequestThrottlingLimit);

  std::unique_ptr<NetworkThrottleManagerImpl::ThrottleImpl> throttle(
      new ThrottleImpl(blocked, priority, delegate, this,
                       blocked_throttles_.end()));

  ThrottleList& insert_list(blocked ? blocked_throttles_
                                    : outstanding_throttles_);

  throttle->set_queue_pointer(
      insert_list.insert(insert_list.end(), throttle.get()));

  // In case oustanding_throttles_ was empty, set up timer.
  if (!blocked)
    RecomputeOutstanding();

  return std::move(throttle);
}

void NetworkThrottleManagerImpl::SetTickClockForTesting(
    const base::TickClock* tick_clock) {
  tick_clock_ = tick_clock;
  DCHECK(!outstanding_recomputation_timer_->IsRunning());
  outstanding_recomputation_timer_ =
      std::make_unique<base::OneShotTimer>(tick_clock_);
}

bool NetworkThrottleManagerImpl::ConditionallyTriggerTimerForTesting() {
  if (!outstanding_recomputation_timer_->IsRunning() ||
      (tick_clock_->NowTicks() <
       outstanding_recomputation_timer_->desired_run_time())) {
    return false;
  }

  base::Closure timer_callback(outstanding_recomputation_timer_->user_task());
  outstanding_recomputation_timer_->Stop();
  timer_callback.Run();
  return true;
}

void NetworkThrottleManagerImpl::OnThrottlePriorityChanged(
    NetworkThrottleManagerImpl::ThrottleImpl* throttle,
    RequestPriority old_priority,
    RequestPriority new_priority) {
  // The only case requiring a state change is if the priority change
  // implies unblocking, which can only happen on a transition from blocked
  // (implies THROTTLED) to non-THROTTLED.
  if (throttle->IsBlocked() && new_priority != THROTTLED) {
    // May result in re-entrant calls into this class.
    UnblockThrottle(throttle);
  }
}

void NetworkThrottleManagerImpl::OnThrottleDestroyed(ThrottleImpl* throttle) {
  switch (throttle->state()) {
    case ThrottleImpl::State::BLOCKED:
      DCHECK(throttle->queue_pointer() != blocked_throttles_.end());
      DCHECK_EQ(throttle, *(throttle->queue_pointer()));
      blocked_throttles_.erase(throttle->queue_pointer());
      break;
    case ThrottleImpl::State::OUTSTANDING:
      DCHECK(throttle->queue_pointer() != outstanding_throttles_.end());
      DCHECK_EQ(throttle, *(throttle->queue_pointer()));
      outstanding_throttles_.erase(throttle->queue_pointer());
      FALLTHROUGH;
    case ThrottleImpl::State::AGED:
      DCHECK(!throttle->start_time().is_null());
      lifetime_median_estimate_.AddSample(
          (tick_clock_->NowTicks() - throttle->start_time())
              .InMillisecondsRoundedUp());
      break;
  }

  DCHECK(!base::ContainsValue(blocked_throttles_, throttle));
  DCHECK(!base::ContainsValue(outstanding_throttles_, throttle));

  // Unblock the throttles if there's some chance there's a throttle to
  // unblock.
  if (outstanding_throttles_.size() < kActiveRequestThrottlingLimit &&
      !blocked_throttles_.empty()) {
    // Via PostTask so there aren't upcalls from within destructors.
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(&NetworkThrottleManagerImpl::MaybeUnblockThrottles,
                   weak_ptr_factory_.GetWeakPtr()));
  }
}

void NetworkThrottleManagerImpl::RecomputeOutstanding() {
  // Remove all throttles that have aged out of the outstanding set.
  base::TimeTicks now(tick_clock_->NowTicks());
  base::TimeDelta age_horizon(base::TimeDelta::FromMilliseconds((
      kMedianLifetimeMultiple * lifetime_median_estimate_.current_estimate())));
  while (!outstanding_throttles_.empty()) {
    ThrottleImpl* throttle = *outstanding_throttles_.begin();
    if (throttle->start_time() + age_horizon >= now)
      break;

    outstanding_throttles_.erase(outstanding_throttles_.begin());
    throttle->SetAged();
    throttle->set_queue_pointer(outstanding_throttles_.end());
  }

  if (outstanding_throttles_.empty())
    return;

  // If the timer is already running, be conservative and leave it alone;
  // the time for which it would be set will only be later than when it's
  // currently set.
  // This addresses, e.g., situations where a RecomputeOutstanding() races
  // with a running timer which would unblock blocked throttles.
  if (outstanding_recomputation_timer_->IsRunning())
    return;

  ThrottleImpl* first_throttle(*outstanding_throttles_.begin());
  DCHECK_GE(first_throttle->start_time() + age_horizon, now);

  outstanding_recomputation_timer_->Start(
      FROM_HERE,
      ((first_throttle->start_time() + age_horizon) - now +
       base::TimeDelta::FromMilliseconds(kTimerFudgeInMs)),
      // Unretained use of |this| is safe because the timer is
      // owned by this object, and will be torn down if this object
      // is destroyed.
      base::Bind(&NetworkThrottleManagerImpl::MaybeUnblockThrottles,
                 base::Unretained(this)));
}

void NetworkThrottleManagerImpl::UnblockThrottle(ThrottleImpl* throttle) {
  DCHECK(throttle->IsBlocked());

  blocked_throttles_.erase(throttle->queue_pointer());
  throttle->set_start_time(tick_clock_->NowTicks());
  throttle->set_queue_pointer(
      outstanding_throttles_.insert(outstanding_throttles_.end(), throttle));

  // Called in case |*throttle| was added to a null set.
  RecomputeOutstanding();

  // May result in re-entrant calls into this class.
  throttle->NotifyUnblocked();
}

void NetworkThrottleManagerImpl::MaybeUnblockThrottles() {
  RecomputeOutstanding();

  while (outstanding_throttles_.size() < kActiveRequestThrottlingLimit &&
         !blocked_throttles_.empty()) {
    // NOTE: This call may result in reentrant calls into
    // NetworkThrottleManagerImpl; no state should be assumed to be
    // persistent across this call.
    UnblockThrottle(blocked_throttles_.front());
  }
}

}  // namespace net
