// Copyright 2020 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 BASE_BIND_POST_TASK_H_
#define BASE_BIND_POST_TASK_H_

#include "base/location.h"

namespace base {

// Helper class to ensure that the input callback is always invoked and
// destroyed on the provided task runner.
template <typename CallbackType>
class BindPostTaskTrampoline {
 public:
  BindPostTaskTrampoline(scoped_refptr<base::TaskRunner> task_runner,
                         const base::Location& location,
                         CallbackType callback)
      : task_runner_(std::move(task_runner)),
        location_(location),
        callback_(std::move(callback)) {
    DCHECK(task_runner_);
    // Crash immediately instead of when trying to Run() `callback_` on the
    // destination `task_runner_`.
    CHECK(callback_);
  }

  BindPostTaskTrampoline(const BindPostTaskTrampoline& other) = delete;
  BindPostTaskTrampoline& operator=(const BindPostTaskTrampoline& other) =
      delete;

  ~BindPostTaskTrampoline() {
    if (callback_) {
      // Post a task to ensure that `callback_` is destroyed on `task_runner_`.
      // The callback's BindState may own an object that isn't threadsafe and is
      // unsafe to destroy on a different task runner.
      //
      // Note that while this guarantees `callback_` will be destroyed when the
      // posted task runs, it doesn't guarantee the ref-counted BindState is
      // destroyed at the same time. If the callback was copied before being
      // passed to BindPostTaskTrampoline then the BindState can outlive
      // `callback_`, so the user must ensure any other copies of the callback
      // are also destroyed on the correct task runner.
      task_runner_->PostTask(location_, BindOnce(&DestroyCallbackOnTaskRunner,
                                                 std::move(callback_)));
    }
  }

  template <typename... Args>
  void Run(Args... args) {
    // If CallbackType is a OnceCallback then GetClosure() consumes `callback_`.
    task_runner_->PostTask(location_,
                           GetClosure(&callback_, std::forward<Args>(args)...));
  }

 private:
  typedef base::OnceClosure OnceClosure;

  static OnceClosure GetClosure(OnceClosure* callback) {
    // `callback` is already a closure, no need to call BindOnce().
    return std::move(*callback);
  }

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

  static OnceClosure GetClosure(base::RepeatingClosure* callback) {
    // `callback` is already a closure, no need to call BindOnce().
    return *callback;
  }

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

  static void DestroyCallbackOnTaskRunner(CallbackType callback) {}

  const scoped_refptr<base::TaskRunner> task_runner_;
  const base::Location location_;
  CallbackType callback_;
};

template <typename ReturnType, typename... Args>
base::OnceCallback<void(Args...)> BindPostTask(
    scoped_refptr<base::TaskRunner> task_runner,
    base::OnceCallback<ReturnType(Args...)> callback,
    const base::Location& location) {
  static_assert(std::is_same<ReturnType, void>::value,
                "OnceCallback must have void return type in order to produce a "
                "closure for PostTask(). Use base::IgnoreResult() to drop the "
                "return value if desired.");

  using Helper = BindPostTaskTrampoline<base::OnceCallback<void(Args...)>>;

  return base::BindOnce(
      &Helper::template Run<Args...>,
      std::make_unique<Helper>(std::move(task_runner), location,
                               std::move(callback)));
}

// Creates a RepeatingCallback that will run |callback| on |task_runner|. When
// the returned callback is destroyed a task will be posted to destroy the input
// |callback| on |task_runner|.
template <typename ReturnType, typename... Args>
base::RepeatingCallback<void(Args...)> BindPostTask(
    scoped_refptr<base::TaskRunner> task_runner,
    base::RepeatingCallback<ReturnType(Args...)> callback,
    const base::Location& location) {
  static_assert(std::is_same<ReturnType, void>::value,
                "RepeatingCallback must have void return type in order to "
                "produce a closure for PostTask(). Use base::IgnoreResult() to "
                "drop the return value if desired.");

  using Helper =
      BindPostTaskTrampoline<base::RepeatingCallback<void(Args...)>>;

  return base::BindRepeating(
      &Helper::template Run<Args...>,
      std::make_unique<Helper>(std::move(task_runner), location,
                               std::move(callback)));
}

}  // namespace base

#endif  // BASE_BIND_POST_TASK_H_
