// Copyright 2015 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 "ui/accelerated_widget_mac/window_resize_helper_mac.h"

#include <stdint.h>

#include <list>

#include "base/bind.h"
#include "base/callback.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_restrictions.h"

namespace ui {
namespace {

class WrappedTask;
class PumpableTaskRunner;
typedef std::list<WrappedTask*> WrappedTaskQueue;
typedef base::Callback<void(base::WaitableEvent*, base::TimeDelta)>
    EventTimedWaitCallback;

// A wrapper for IPCs and tasks that we may potentially execute in
// WaitForSingleTaskToRun. Because these tasks are sent to two places to run,
// we to wrap them in this structure and track whether or not they have run
// yet, to avoid running them twice.
class WrappedTask {
 public:
  WrappedTask(const base::Closure& closure, base::TimeDelta delay);
  ~WrappedTask();
  bool ShouldRunBefore(const WrappedTask& other);
  void Run();
  void AddToTaskRunnerQueue(PumpableTaskRunner* pumpable_task_runner);
  void RemoveFromTaskRunnerQueue();
  const base::TimeTicks& can_run_time() const { return can_run_time_; }

 private:
  base::Closure closure_;
  base::TimeTicks can_run_time_;
  bool has_run_;
  uint64_t sequence_number_;
  WrappedTaskQueue::iterator iterator_;

  // Back pointer to the pumpable task runner that this task is enqueued in.
  scoped_refptr<PumpableTaskRunner> pumpable_task_runner_;

  DISALLOW_COPY_AND_ASSIGN(WrappedTask);
};

// The PumpableTaskRunner is a task runner that will wrap tasks in an
// WrappedTask, enqueues that wrapped task in the queue to be pumped via
// WaitForSingleWrappedTaskToRun during resizes, and posts the task to a
// target task runner. The posted task will run only once, either through a
// WaitForSingleWrappedTaskToRun call or through the target task runner.
class PumpableTaskRunner : public base::SingleThreadTaskRunner {
 public:
  PumpableTaskRunner(
      const EventTimedWaitCallback& event_timed_wait_callback,
      const scoped_refptr<base::SingleThreadTaskRunner>& target_task_runner);

  // Enqueue WrappedTask and post it to |target_task_runner_|.
  bool EnqueueAndPostWrappedTask(const tracked_objects::Location& from_here,
                                 WrappedTask* task,
                                 base::TimeDelta delay);

  // Wait at most |max_delay| to run an enqueued task.
  bool WaitForSingleWrappedTaskToRun(const base::TimeDelta& max_delay);

  // base::SingleThreadTaskRunner implementation:
  bool PostDelayedTask(const tracked_objects::Location& from_here,
                       const base::Closure& task,
                       base::TimeDelta delay) override;

  bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
                                  const base::Closure& task,
                                  base::TimeDelta delay) override;

  bool RunsTasksOnCurrentThread() const override;

 private:
  friend class WrappedTask;

  ~PumpableTaskRunner() override;

  // A queue of live messages.  Must hold |task_queue_lock_| to access. Tasks
  // are added only on the IO thread and removed only on the UI thread.  The
  // WrappedTask objects are removed from the queue when they are run (by
  // |target_task_runner_| or by a call to WaitForSingleWrappedTaskToRun
  // removing them out of the queue, or by TaskRunner when it is destroyed).
  WrappedTaskQueue task_queue_;
  base::Lock task_queue_lock_;

  // Event used to wake up the UI thread if it is sleeping in
  // WaitForSingleTaskToRun.
  base::WaitableEvent event_;

  // Callback to call TimedWait on |event_| from an appropriate class.
  EventTimedWaitCallback event_timed_wait_callback_;

  scoped_refptr<base::SingleThreadTaskRunner> target_task_runner_;

  DISALLOW_COPY_AND_ASSIGN(PumpableTaskRunner);
};

base::LazyInstance<WindowResizeHelperMac>::Leaky g_window_resize_helper =
    LAZY_INSTANCE_INITIALIZER;

////////////////////////////////////////////////////////////////////////////////
// WrappedTask

WrappedTask::WrappedTask(const base::Closure& closure, base::TimeDelta delay)
    : closure_(closure),
      can_run_time_(base::TimeTicks::Now() + delay),
      has_run_(false),
      sequence_number_(0) {}

WrappedTask::~WrappedTask() {
  RemoveFromTaskRunnerQueue();
}

bool WrappedTask::ShouldRunBefore(const WrappedTask& other) {
  if (can_run_time_ < other.can_run_time_)
    return true;
  if (can_run_time_ > other.can_run_time_)
    return false;
  if (sequence_number_ < other.sequence_number_)
    return true;
  if (sequence_number_ > other.sequence_number_)
    return false;
  // Sequence numbers are unique, so this should never happen.
  NOTREACHED();
  return false;
}

void WrappedTask::Run() {
  if (has_run_)
    return;
  RemoveFromTaskRunnerQueue();
  has_run_ = true;
  closure_.Run();
}

void WrappedTask::AddToTaskRunnerQueue(
    PumpableTaskRunner* pumpable_task_runner) {
  pumpable_task_runner_ = pumpable_task_runner;
  base::AutoLock lock(pumpable_task_runner_->task_queue_lock_);
  static uint64_t last_sequence_number = 0;
  last_sequence_number += 1;
  sequence_number_ = last_sequence_number;
  iterator_ = pumpable_task_runner_->task_queue_.insert(
      pumpable_task_runner_->task_queue_.end(), this);
}

void WrappedTask::RemoveFromTaskRunnerQueue() {
  if (!pumpable_task_runner_.get())
    return;
  // The scope of the task runner's lock must be limited because removing
  // this reference to the task runner may destroy it.
  {
    base::AutoLock lock(pumpable_task_runner_->task_queue_lock_);
    pumpable_task_runner_->task_queue_.erase(iterator_);
    iterator_ = pumpable_task_runner_->task_queue_.end();
  }
  pumpable_task_runner_ = NULL;
}

////////////////////////////////////////////////////////////////////////////////
// PumpableTaskRunner

PumpableTaskRunner::PumpableTaskRunner(
    const EventTimedWaitCallback& event_timed_wait_callback,
    const scoped_refptr<base::SingleThreadTaskRunner>& target_task_runner)
    : event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
             base::WaitableEvent::InitialState::NOT_SIGNALED),
      event_timed_wait_callback_(event_timed_wait_callback),
      target_task_runner_(target_task_runner) {}

PumpableTaskRunner::~PumpableTaskRunner() {
  // Because tasks hold a reference to the task runner, the task queue must
  // be empty when it is destroyed.
  DCHECK(task_queue_.empty());
}

bool PumpableTaskRunner::WaitForSingleWrappedTaskToRun(
    const base::TimeDelta& max_delay) {
  base::TimeTicks stop_waiting_time = base::TimeTicks::Now() + max_delay;

  for (;;) {
    base::TimeTicks current_time = base::TimeTicks::Now();
    base::TimeTicks next_task_time = stop_waiting_time;

    // Find the first task to execute in the list. This lookup takes O(n) time,
    // but n is rarely more than 2, and has never been observed to be more than
    // 12.
    WrappedTask* task_to_execute = NULL;
    {
      base::AutoLock lock(task_queue_lock_);

      for (WrappedTaskQueue::iterator it = task_queue_.begin();
           it != task_queue_.end(); ++it) {
        WrappedTask* potential_task = *it;

        // If this task is scheduled for the future, take it into account when
        // deciding how long to sleep, and continue on to the next task.
        if (potential_task->can_run_time() > current_time) {
          if (potential_task->can_run_time() < next_task_time)
            next_task_time = potential_task->can_run_time();
          continue;
        }
        // If there is a better candidate than this task, continue to the next
        // task.
        if (task_to_execute &&
            task_to_execute->ShouldRunBefore(*potential_task)) {
          continue;
        }
        task_to_execute = potential_task;
      }
    }

    if (task_to_execute) {
      task_to_execute->Run();
      return true;
    }

    // Calculate how much time we have left before we have to stop waiting or
    // until a currently-enqueued task will be ready to run.
    base::TimeDelta max_sleep_time = next_task_time - current_time;
    if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0))
      break;

    event_timed_wait_callback_.Run(&event_, max_sleep_time);
  }

  return false;
}

bool PumpableTaskRunner::EnqueueAndPostWrappedTask(
    const tracked_objects::Location& from_here,
    WrappedTask* task,
    base::TimeDelta delay) {
  task->AddToTaskRunnerQueue(this);

  // Notify anyone waiting on the UI thread that there is a new entry in the
  // task map.  If they don't find the entry they are looking for, then they
  // will just continue waiting.
  event_.Signal();

  return target_task_runner_->PostDelayedTask(
      from_here, base::Bind(&WrappedTask::Run, base::Owned(task)), delay);
}

////////////////////////////////////////////////////////////////////////////////
// PumpableTaskRunner, base::SingleThreadTaskRunner implementation:

bool PumpableTaskRunner::PostDelayedTask(
    const tracked_objects::Location& from_here,
    const base::Closure& task,
    base::TimeDelta delay) {
  return EnqueueAndPostWrappedTask(from_here, new WrappedTask(task, delay),
                                   delay);
}

bool PumpableTaskRunner::PostNonNestableDelayedTask(
    const tracked_objects::Location& from_here,
    const base::Closure& task,
    base::TimeDelta delay) {
  // The correctness of non-nestable events hasn't been proven for this
  // structure.
  NOTREACHED();
  return false;
}

bool PumpableTaskRunner::RunsTasksOnCurrentThread() const {
  return target_task_runner_->RunsTasksOnCurrentThread();
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// WindowResizeHelperMac

scoped_refptr<base::SingleThreadTaskRunner> WindowResizeHelperMac::task_runner()
    const {
  return task_runner_;
}

// static
WindowResizeHelperMac* WindowResizeHelperMac::Get() {
  return g_window_resize_helper.Pointer();
}

void WindowResizeHelperMac::Init(
    const scoped_refptr<base::SingleThreadTaskRunner>& target_task_runner) {
  DCHECK(!task_runner_);
  task_runner_ = new PumpableTaskRunner(
      base::Bind(&WindowResizeHelperMac::EventTimedWait), target_task_runner);
}

void WindowResizeHelperMac::ShutdownForTests() {
  task_runner_ = nullptr;
}

bool WindowResizeHelperMac::WaitForSingleTaskToRun(
    const base::TimeDelta& max_delay) {
  PumpableTaskRunner* pumpable_task_runner =
      static_cast<PumpableTaskRunner*>(task_runner_.get());
  if (!pumpable_task_runner)
    return false;
  return pumpable_task_runner->WaitForSingleWrappedTaskToRun(max_delay);
}

WindowResizeHelperMac::WindowResizeHelperMac() {}
WindowResizeHelperMac::~WindowResizeHelperMac() {}

void WindowResizeHelperMac::EventTimedWait(base::WaitableEvent* event,
                                           base::TimeDelta delay) {
  base::ThreadRestrictions::ScopedAllowWait allow_wait;
  event->TimedWait(delay);
}

}  // namespace ui
