// Copyright 2013 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 "extensions/common/one_shot_event.h"

#include "base/callback.h"
#include "base/lazy_instance.h"
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/task_runner.h"
#include "base/time/time.h"

using base::TaskRunner;

namespace extensions {

struct OneShotEvent::TaskInfo {
  TaskInfo() {}
  TaskInfo(const tracked_objects::Location& from_here,
           const scoped_refptr<TaskRunner>& runner,
           const base::Closure& task,
           const base::TimeDelta& delay)
      : from_here(from_here), runner(runner), task(task), delay(delay) {
    CHECK(runner.get());  // Detect mistakes with a decent stack frame.
  }
  tracked_objects::Location from_here;
  scoped_refptr<TaskRunner> runner;
  base::Closure task;
  base::TimeDelta delay;
};

OneShotEvent::OneShotEvent() : signaled_(false) {
  // It's acceptable to construct the OneShotEvent on one thread, but
  // immediately move it to another thread.
  thread_checker_.DetachFromThread();
}
OneShotEvent::OneShotEvent(bool signaled) : signaled_(signaled) {
  thread_checker_.DetachFromThread();
}
OneShotEvent::~OneShotEvent() {}

void OneShotEvent::Post(const tracked_objects::Location& from_here,
                        const base::Closure& task) const {
  PostImpl(
      from_here, task, base::MessageLoopProxy::current(), base::TimeDelta());
}

void OneShotEvent::Post(const tracked_objects::Location& from_here,
                        const base::Closure& task,
                        const scoped_refptr<TaskRunner>& runner) const {
  PostImpl(from_here, task, runner, base::TimeDelta());
}

void OneShotEvent::PostDelayed(const tracked_objects::Location& from_here,
                               const base::Closure& task,
                               const base::TimeDelta& delay) const {
  PostImpl(from_here, task, base::MessageLoopProxy::current(), delay);
}

void OneShotEvent::Signal() {
  DCHECK(thread_checker_.CalledOnValidThread());

  CHECK(!signaled_) << "Only call Signal once.";

  signaled_ = true;
  // After this point, a call to Post() from one of the queued tasks
  // could proceed immediately, but the fact that this object is
  // single-threaded prevents that from being relevant.

  // We could randomize tasks_ in debug mode in order to check that
  // the order doesn't matter...
  for (size_t i = 0; i < tasks_.size(); ++i) {
    const TaskInfo& task = tasks_[i];
    if (task.delay != base::TimeDelta())
      task.runner->PostDelayedTask(task.from_here, task.task, task.delay);
    else
      task.runner->PostTask(task.from_here, task.task);
  }
}

void OneShotEvent::PostImpl(const tracked_objects::Location& from_here,
                            const base::Closure& task,
                            const scoped_refptr<TaskRunner>& runner,
                            const base::TimeDelta& delay) const {
  DCHECK(thread_checker_.CalledOnValidThread());

  if (is_signaled()) {
    if (delay != base::TimeDelta())
      runner->PostDelayedTask(from_here, task, delay);
    else
      runner->PostTask(from_here, task);
  } else {
    tasks_.push_back(TaskInfo(from_here, runner, task, delay));
  }
}

}  // namespace extensions
