// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_
#define BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_

#include <functional>
#include <tuple>
#include <type_traits>
#include <utility>

#include "base/functional/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_refptr.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace base {

namespace gmock_callback_support_internal {

// Small helper to get the `I`th argument.
template <size_t I, typename... Args>
decltype(auto) get(Args&&... args) {
  return std::get<I>(std::forward_as_tuple(std::forward<Args>(args)...));
}

// Invokes `cb` with the arguments stored in `tuple`. Both `cb` and `tuple` are
// perfectly forwarded, allowing callers to specify whether they should be
// passed by move or copy.
template <typename Callback, typename Tuple, size_t... Is>
decltype(auto) RunImpl(Callback&& cb,
                       Tuple&& tuple,
                       std::index_sequence<Is...>) {
  return std::forward<Callback>(cb).Run(
      std::get<Is>(std::forward<Tuple>(tuple))...);
}

// Invokes `cb` with the arguments stored in `tuple`. Both `cb` and `tuple` are
// perfectly forwarded, allowing callers to specify whether they should be
// passed by move or copy. Needs to dispatch to the three arguments version to
// be able to construct a `std::index_sequence` of the corresponding size.
template <typename Callback, typename Tuple>
decltype(auto) RunImpl(Callback&& cb, Tuple&& tuple) {
  return RunImpl(std::forward<Callback>(cb), std::forward<Tuple>(tuple),
                 std::make_index_sequence<
                     std::tuple_size<std::remove_reference_t<Tuple>>::value>());
}

// Invoked when the arguments to a OnceCallback are copy constructible. In this
// case the returned lambda will pass the arguments to the provided callback by
// copy, allowing it to be used multiple times.
template <size_t I,
          typename Tuple,
          std::enable_if_t<std::is_copy_constructible<Tuple>::value, int> = 0>
auto RunOnceCallbackImpl(Tuple&& tuple) {
  return
      [tuple = std::forward<Tuple>(tuple)](auto&&... args) -> decltype(auto) {
        return RunImpl(
            std::move(::base::gmock_callback_support_internal::get<I>(args...)),
            tuple);
      };
}

// Invoked when the arguments to a OnceCallback are not copy constructible. In
// this case the returned lambda will pass the arguments to the provided
// callback by move, allowing it to be only used once.
template <size_t I,
          typename Tuple,
          std::enable_if_t<!std::is_copy_constructible<Tuple>::value, int> = 0>
auto RunOnceCallbackImpl(Tuple&& tuple) {
  // Mock actions need to be copyable, but `tuple` is not. Wrap it in in a
  // `scoped_refptr` to allow it to be copied.
  auto tuple_ptr = base::MakeRefCounted<base::RefCountedData<Tuple>>(
      std::forward<Tuple>(tuple));
  return [tuple_ptr =
              std::move(tuple_ptr)](auto&&... args) mutable -> decltype(auto) {
    // Since running the action will move out of the arguments, `tuple_ptr` is
    // nulled out, so that attempting to run it twice will result in a run-time
    // crash.
    return RunImpl(
        std::move(::base::gmock_callback_support_internal::get<I>(args...)),
        std::move(std::exchange(tuple_ptr, nullptr)->data));
  };
}

// Invoked for RepeatingCallbacks. In this case the returned lambda will pass
// the arguments to the provided callback by copy, allowing it to be used
// multiple times. Move-only arguments are not supported.
template <size_t I, typename Tuple>
auto RunRepeatingCallbackImpl(Tuple&& tuple) {
  return
      [tuple = std::forward<Tuple>(tuple)](auto&&... args) -> decltype(auto) {
        return RunImpl(::base::gmock_callback_support_internal::get<I>(args...),
                       tuple);
      };
}

}  // namespace gmock_callback_support_internal

namespace test {

// Matchers for base::{Once,Repeating}Callback and
// base::{Once,Repeating}Closure.
MATCHER(IsNullCallback, "a null callback") {
  return (arg.is_null());
}

MATCHER(IsNotNullCallback, "a non-null callback") {
  return (!arg.is_null());
}

// The Run[Once]Closure() action invokes the Run() method on the closure
// provided when the action is constructed. Function arguments passed when the
// action is run will be ignored.
ACTION_P(RunClosure, closure) {
  closure.Run();
}

// This action can be invoked at most once. Any further invocation will trigger
// a CHECK failure.
inline auto RunOnceClosure(base::OnceClosure cb) {
  // Mock actions need to be copyable, but OnceClosure is not. Wrap the closure
  // in a base::RefCountedData<> to allow it to be copied.
  using RefCountedOnceClosure = base::RefCountedData<base::OnceClosure>;
  scoped_refptr<RefCountedOnceClosure> copyable_cb =
      base::MakeRefCounted<RefCountedOnceClosure>(std::move(cb));
  return [copyable_cb](auto&&...) {
    CHECK(copyable_cb->data);
    std::move(copyable_cb->data).Run();
  };
}

// The Run[Once]Closure<N>() action invokes the Run() method on the N-th
// (0-based) argument of the mock function.
template <size_t I>
auto RunClosure() {
  return [](auto&&... args) -> decltype(auto) {
    return ::base::gmock_callback_support_internal::get<I>(args...).Run();
  };
}

template <size_t I>
auto RunOnceClosure() {
  return [](auto&&... args) -> decltype(auto) {
    return std::move(::base::gmock_callback_support_internal::get<I>(args...))
        .Run();
  };
}

// The Run[Once]Callback<N>(p1, p2, ..., p_k) action invokes the Run() method on
// the N-th (0-based) argument of the mock function, with arguments p1, p2, ...,
// p_k.
//
// Notes:
//
//   1. The arguments are passed by value by default.  If you need to
//   pass an argument by reference, wrap it inside ByRef().  For example,
//
//     RunCallback<1>(5, string("Hello"), ByRef(foo))
//
//   passes 5 and string("Hello") by value, and passes foo by reference.
//
//   2. If the callback takes an argument by reference but ByRef() is
//   not used, it will receive the reference to a copy of the value,
//   instead of the original value.  For example, when the 0-th
//   argument of the callback takes a const string&, the action
//
//     RunCallback<0>(string("Hello"))
//
//   makes a copy of the temporary string("Hello") object and passes a
//   reference of the copy, instead of the original temporary object,
//   to the callback.  This makes it easy for a user to define an
//   RunCallback action from temporary values and have it performed later.
//
//   3. In order to facilitate re-use of the `RunOnceCallback()` action,
//   the arguments are copied during each run if possible. If this can't
//   be done (e.g. one of the arguments is move-only), the arguments will
//   be passed by move. However, since moving potentially invalidates the
//   arguments, the resulting action is only allowed to run once in this
//   case. Attempting to run it twice will result in a runtime crash.
//   Using move-only arguments with `RunCallback()` is not supported.
template <size_t I, typename... RunArgs>
auto RunOnceCallback(RunArgs&&... run_args) {
  return ::base::gmock_callback_support_internal::RunOnceCallbackImpl<I>(
      std::make_tuple(std::forward<RunArgs>(run_args)...));
}

template <size_t I, typename... RunArgs>
auto RunCallback(RunArgs&&... run_args) {
  return ::base::gmock_callback_support_internal::RunRepeatingCallbackImpl<I>(
      std::make_tuple(std::forward<RunArgs>(run_args)...));
}

}  // namespace test
}  // namespace base

#endif  // BASE_TEST_GMOCK_CALLBACK_SUPPORT_H_
