// Copyright (c) 2018 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/prioritized_task_runner.h"

#include <algorithm>

#include "base/bind.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"

namespace net {

PrioritizedTaskRunner::Job::Job(const base::Location& from_here,
                                base::OnceClosure task,
                                base::OnceClosure reply,
                                uint32_t priority,
                                uint32_t task_count)
    : from_here(from_here),
      task(std::move(task)),
      reply(std::move(reply)),
      priority(priority),
      task_count(task_count) {}

PrioritizedTaskRunner::Job::Job() {}

PrioritizedTaskRunner::Job::~Job() = default;
PrioritizedTaskRunner::Job::Job(Job&& other) = default;
PrioritizedTaskRunner::Job& PrioritizedTaskRunner::Job::operator=(Job&& other) =
    default;

PrioritizedTaskRunner::PrioritizedTaskRunner(
    scoped_refptr<base::TaskRunner> task_runner)
    : task_runner_(std::move(task_runner)) {}

void PrioritizedTaskRunner::PostTaskAndReply(const base::Location& from_here,
                                             base::OnceClosure task,
                                             base::OnceClosure reply,
                                             uint32_t priority) {
  Job job(from_here, std::move(task), std::move(reply), priority,
          task_count_++);
  {
    base::AutoLock lock(task_job_heap_lock_);
    task_job_heap_.push_back(std::move(job));
    std::push_heap(task_job_heap_.begin(), task_job_heap_.end(), JobComparer());
  }

  task_runner_->PostTaskAndReply(
      from_here,
      base::BindOnce(&PrioritizedTaskRunner::RunPostTaskAndReply, this),
      base::BindOnce(&PrioritizedTaskRunner::RunReply, this));
}

PrioritizedTaskRunner::~PrioritizedTaskRunner() = default;

void PrioritizedTaskRunner::RunPostTaskAndReply() {
  DCHECK(task_runner_->RunsTasksInCurrentSequence());

  // Find the next job to run.
  Job job;
  {
    base::AutoLock lock(task_job_heap_lock_);
    std::pop_heap(task_job_heap_.begin(), task_job_heap_.end(), JobComparer());
    job = std::move(task_job_heap_.back());
    task_job_heap_.pop_back();
  }

  std::move(job.task).Run();

  // Add the job to the reply priority queue.
  base::AutoLock reply_lock(reply_job_heap_lock_);
  reply_job_heap_.push_back(std::move(job));
  std::push_heap(reply_job_heap_.begin(), reply_job_heap_.end(), JobComparer());
}

void PrioritizedTaskRunner::RunReply() {
  // Find the next job to run.
  Job job;
  {
    base::AutoLock lock(reply_job_heap_lock_);
    std::pop_heap(reply_job_heap_.begin(), reply_job_heap_.end(),
                  JobComparer());
    job = std::move(reply_job_heap_.back());
    reply_job_heap_.pop_back();
  }

  // Run the job.
  std::move(job.reply).Run();
}

}  // namespace net
