// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef EXTENSIONS_BROWSER_UPDATER_REQUEST_QUEUE_IMPL_H_
#define EXTENSIONS_BROWSER_UPDATER_REQUEST_QUEUE_IMPL_H_

#include <stddef.h>

#include <algorithm>
#include <memory>
#include <utility>

#include "base/compiler_specific.h"
#include "base/functional/bind.h"
#include "extensions/browser/updater/request_queue.h"

namespace extensions {

template <typename T>
RequestQueue<T>::RequestQueue(
    net::BackoffEntry::Policy backoff_policy,
    const base::RepeatingClosure& start_request_callback)
    : backoff_policy_(backoff_policy),
      start_request_callback_(start_request_callback),
      active_request_(absl::nullopt) {}

template <typename T>
RequestQueue<T>::~RequestQueue() = default;

template <typename T>
T* RequestQueue<T>::active_request() {
  return active_request_ ? active_request_->fetch.get() : nullptr;
}

template <typename T>
int RequestQueue<T>::active_request_failure_count() {
  DCHECK(active_request_);
  return active_request_->backoff_entry->failure_count();
}

template <typename T>
typename RequestQueue<T>::Request RequestQueue<T>::reset_active_request() {
  DCHECK(active_request_);
  Request request = std::move(*active_request_);
  active_request_.reset();
  return request;
}

template <typename T>
void RequestQueue<T>::ScheduleRequest(std::unique_ptr<T> request) {
  PushImpl(Request(std::unique_ptr<net::BackoffEntry>(
                       new net::BackoffEntry(&backoff_policy_)),
                   std::move(request)));
  StartNextRequest();
}

template <typename T>
void RequestQueue<T>::ScheduleRetriedRequest(
    Request request,
    const base::TimeDelta& min_backoff_delay) {
  DCHECK(request.backoff_entry);
  DCHECK(request.fetch);
  request.backoff_entry->InformOfRequest(false);
  if (request.backoff_entry->GetTimeUntilRelease() < min_backoff_delay) {
    request.backoff_entry->SetCustomReleaseTime(base::TimeTicks::Now() +
                                                min_backoff_delay);
  }
  PushImpl(std::move(request));
}

template <typename T>
void RequestQueue<T>::PushImpl(Request request) {
  pending_requests_.push_back(std::move(request));
  std::push_heap(
      pending_requests_.begin(), pending_requests_.end(), CompareRequests);
}

template <typename T>
bool RequestQueue<T>::empty() const {
  return pending_requests_.empty();
}

template <typename T>
size_t RequestQueue<T>::size() const {
  return pending_requests_.size();
}

template <typename T>
base::TimeTicks RequestQueue<T>::NextReleaseTime() const {
  return pending_requests_.front().backoff_entry->GetReleaseTime();
}

template <typename T>
void RequestQueue<T>::StartNextRequest() {
  if (active_request_)
    // Already running a request, assume this method will be called again when
    // the request is done.
    return;

  if (empty())
    // No requests in the queue, so we're done.
    return;

  base::TimeTicks next_release = NextReleaseTime();
  base::TimeTicks now = base::TimeTicks::Now();
  if (next_release > now) {
    // Not ready for the next update check yet, call this method when it is
    // time.
    timer_.Start(FROM_HERE, next_release - now,
                 base::BindOnce(&RequestQueue<T>::StartNextRequest,
                                base::Unretained(this)));
    return;
  }

  // pop_heap swaps the first and last elements of pending_requests_, and after
  // that assures that the rest of pending_requests_ (excluding the
  // now last/formerly first element) forms a proper heap. After pop_heap
  // [begin, end-1) is a valid heap, and *(end - 1) contains the element that
  // used to be at the top of the heap. Since no elements are actually
  // removed from the container it is safe to read the entry being removed after
  // pop_heap is called (but before pop_back is called).
  std::pop_heap(
      pending_requests_.begin(), pending_requests_.end(), CompareRequests);

  active_request_ = std::move(pending_requests_.back());

  pending_requests_.pop_back();

  start_request_callback_.Run();
}

template <typename T>
void RequestQueue<T>::RetryRequest(const base::TimeDelta& min_backoff_delay) {
  DCHECK(active_request_);
  ScheduleRetriedRequest(reset_active_request(), min_backoff_delay);
}

template <typename T>
typename RequestQueue<T>::iterator RequestQueue<T>::begin() {
  return iterator(pending_requests_.begin());
}

template <typename T>
typename RequestQueue<T>::iterator RequestQueue<T>::end() {
  return iterator(pending_requests_.end());
}

template <typename T>
std::vector<std::unique_ptr<T>> RequestQueue<T>::erase_if(
    base::RepeatingCallback<bool(const T&)> condition) {
  std::vector<std::unique_ptr<T>> erased_fetches;
  for (size_t i = 0; i < pending_requests_.size();) {
    if (condition.Run(*pending_requests_[i].fetch)) {
      erased_fetches.emplace_back(std::move(pending_requests_[i].fetch));
      std::swap(pending_requests_[i],
                pending_requests_[pending_requests_.size() - 1]);
      pending_requests_.pop_back();
    } else {
      i++;
    }
  }
  // We need to maintain a heap structure on pending request in order to extract
  // first ones, but removing might break this structure.
  std::make_heap(pending_requests_.begin(), pending_requests_.end(),
                 CompareRequests);

  return erased_fetches;
}

template <typename T>
void RequestQueue<T>::set_backoff_policy(
    const net::BackoffEntry::Policy backoff_policy) {
  backoff_policy_ = backoff_policy;
}

// static
template <typename T>
bool RequestQueue<T>::CompareRequests(const Request& a, const Request& b) {
  return a.backoff_entry->GetReleaseTime() > b.backoff_entry->GetReleaseTime();
}

}  // namespace extensions

#endif  // EXTENSIONS_BROWSER_UPDATER_REQUEST_QUEUE_IMPL_H_
