// Copyright (c) 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.

#ifndef MEDIA_BASE_BIND_TO_CURRENT_LOOP_H_
#define MEDIA_BASE_BIND_TO_CURRENT_LOOP_H_

#include <memory>

#include "base/bind.h"
#include "base/location.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/sequenced_task_runner_handle.h"

// This is a helper utility for base::Bind()ing callbacks to a given
// TaskRunner. The typical use is when |a| (of class |A|) wants to hand a
// callback such as base::Bind(&A::AMethod, a) to |b|, but needs to ensure that
// when |b| executes the callback, it does so on |a|'s task_runner's
// MessageLoop.
//
// Typical usage: request to be called back on the current thread:
// other->StartAsyncProcessAndCallMeBack(
//    media::BindToLoop(task_runner, base::BindOnce(&MyClass::MyMethod, this)));
//
// media::BindToLoop returns the same type of callback to the given
// callback. I.e. it returns a RepeatingCallback for a given RepeatingCallback,
// and returns OnceCallback for a given OnceCallback.
//
// The function BindToCurrentLoop is shorthand to bind to the calling function's
// current MessageLoop.

namespace media {
namespace internal {

template <typename Signature, typename... Args>
base::OnceClosure MakeClosure(base::RepeatingCallback<Signature>* callback,
                              Args&&... args) {
  return base::BindOnce(*callback, std::forward<Args>(args)...);
}

template <typename Signature, typename... Args>
base::OnceClosure MakeClosure(base::OnceCallback<Signature>* callback,
                              Args&&... args) {
  return base::BindOnce(std::move(*callback), std::forward<Args>(args)...);
}

template <typename CallbackType>
class TrampolineHelper {
 public:
  TrampolineHelper(const base::Location& posted_from,
                   scoped_refptr<base::SequencedTaskRunner> task_runner,
                   CallbackType callback)
      : posted_from_(posted_from),
        task_runner_(std::move(task_runner)),
        callback_(std::move(callback)) {
    DCHECK(task_runner_);
    DCHECK(callback_);
  }

  template <typename... Args>
  void Run(Args... args) {
    // MakeClosure consumes |callback_| if it's OnceCallback.
    task_runner_->PostTask(
        posted_from_, MakeClosure(&callback_, std::forward<Args>(args)...));
  }

  ~TrampolineHelper() {
    if (callback_) {
      task_runner_->PostTask(
          posted_from_,
          base::BindOnce(&TrampolineHelper::ClearCallbackOnTargetTaskRunner,
                         std::move(callback_)));
    }
  }

 private:
  static void ClearCallbackOnTargetTaskRunner(CallbackType) {}

  base::Location posted_from_;
  scoped_refptr<base::SequencedTaskRunner> task_runner_;
  CallbackType callback_;
};

}  // namespace internal

template <typename... Args>
inline base::RepeatingCallback<void(Args...)> BindToLoop(
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    base::RepeatingCallback<void(Args...)> cb) {
  using CallbackType = base::RepeatingCallback<void(Args...)>;
  using Helper = internal::TrampolineHelper<CallbackType>;
  using RunnerType = void (Helper::*)(Args...);
  RunnerType run = &Helper::Run;
  // TODO(tzik): Propagate FROM_HERE from the caller.
  return base::BindRepeating(
      run, std::make_unique<Helper>(FROM_HERE, task_runner, std::move(cb)));
}

template <typename... Args>
inline base::OnceCallback<void(Args...)> BindToLoop(
    scoped_refptr<base::SequencedTaskRunner> task_runner,
    base::OnceCallback<void(Args...)> cb) {
  using CallbackType = base::OnceCallback<void(Args...)>;
  using Helper = internal::TrampolineHelper<CallbackType>;
  using RunnerType = void (Helper::*)(Args...);
  RunnerType run = &Helper::Run;
  // TODO(tzik): Propagate FROM_HERE from the caller.
  return base::BindOnce(
      run, std::make_unique<Helper>(FROM_HERE, task_runner, std::move(cb)));
}

template <typename... Args>
inline base::RepeatingCallback<void(Args...)> BindToCurrentLoop(
    base::RepeatingCallback<void(Args...)> cb) {
  return BindToLoop(base::SequencedTaskRunnerHandle::Get(), std::move(cb));
}

template <typename... Args>
inline base::OnceCallback<void(Args...)> BindToCurrentLoop(
    base::OnceCallback<void(Args...)> cb) {
  return BindToLoop(base::SequencedTaskRunnerHandle::Get(), std::move(cb));
}

}  // namespace media

#endif  // MEDIA_BASE_BIND_TO_CURRENT_LOOP_H_
