// Copyright (c) 2012 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 "media/base/serial_runner.h"

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/thread_task_runner_handle.h"

namespace media {

// Converts a Closure into a bound function accepting a PipelineStatusCB.
static void RunClosure(
    const base::Closure& closure,
    const PipelineStatusCB& status_cb) {
  closure.Run();
  status_cb.Run(PIPELINE_OK);
}

// Converts a bound function accepting a Closure into a bound function
// accepting a PipelineStatusCB. Since closures have no way of reporting a
// status |status_cb| is executed with PIPELINE_OK.
static void RunBoundClosure(
    const SerialRunner::BoundClosure& bound_closure,
    const PipelineStatusCB& status_cb) {
  bound_closure.Run(base::Bind(status_cb, PIPELINE_OK));
}

// Runs |status_cb| with |last_status| on |task_runner|.
static void RunOnTaskRunner(
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    const PipelineStatusCB& status_cb,
    PipelineStatus last_status) {
  // Force post to permit cancellation of a series in the scenario where all
  // bound functions run on the same thread.
  task_runner->PostTask(FROM_HERE, base::Bind(status_cb, last_status));
}

SerialRunner::Queue::Queue() {}
SerialRunner::Queue::~Queue() {}

void SerialRunner::Queue::Push(const base::Closure& closure) {
  bound_fns_.push(base::Bind(&RunClosure, closure));
}

void SerialRunner::Queue::Push(
    const BoundClosure& bound_closure) {
  bound_fns_.push(base::Bind(&RunBoundClosure, bound_closure));
}

void SerialRunner::Queue::Push(
    const BoundPipelineStatusCB& bound_status_cb) {
  bound_fns_.push(bound_status_cb);
}

SerialRunner::BoundPipelineStatusCB SerialRunner::Queue::Pop() {
  BoundPipelineStatusCB bound_fn = bound_fns_.front();
  bound_fns_.pop();
  return bound_fn;
}

bool SerialRunner::Queue::empty() {
  return bound_fns_.empty();
}

SerialRunner::SerialRunner(const Queue& bound_fns,
                           const PipelineStatusCB& done_cb)
    : task_runner_(base::ThreadTaskRunnerHandle::Get()),
      bound_fns_(bound_fns),
      done_cb_(done_cb),
      weak_factory_(this) {
  // Respect both cancellation and calling stack guarantees for |done_cb|
  // when empty.
  if (bound_fns_.empty()) {
    task_runner_->PostTask(FROM_HERE,
                           base::Bind(&SerialRunner::RunNextInSeries,
                                      weak_factory_.GetWeakPtr(),
                                      PIPELINE_OK));
    return;
  }

  RunNextInSeries(PIPELINE_OK);
}

SerialRunner::~SerialRunner() {}

scoped_ptr<SerialRunner> SerialRunner::Run(
    const Queue& bound_fns, const PipelineStatusCB& done_cb) {
  scoped_ptr<SerialRunner> callback_series(
      new SerialRunner(bound_fns, done_cb));
  return callback_series;
}

void SerialRunner::RunNextInSeries(PipelineStatus last_status) {
  DCHECK(task_runner_->BelongsToCurrentThread());
  DCHECK(!done_cb_.is_null());

  if (bound_fns_.empty() || last_status != PIPELINE_OK) {
    base::ResetAndReturn(&done_cb_).Run(last_status);
    return;
  }

  BoundPipelineStatusCB bound_fn = bound_fns_.Pop();
  bound_fn.Run(base::Bind(
      &RunOnTaskRunner,
      task_runner_,
      base::Bind(&SerialRunner::RunNextInSeries, weak_factory_.GetWeakPtr())));
}

}  // namespace media
