//
// Copyright 2019 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_
#define ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_

#include <type_traits>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/random/internal/mock_helpers.h"
#include "absl/random/mocking_bit_gen.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {

template <typename DistrT, typename Fn>
struct MockSingleOverload;

// MockSingleOverload
//
// MockSingleOverload hooks in to gMock's `ON_CALL` and `EXPECT_CALL` macros.
// EXPECT_CALL(mock_single_overload, Call(...))` will expand to a call to
// `mock_single_overload.gmock_Call(...)`. Because expectations are stored on
// the MockingBitGen (an argument passed inside `Call(...)`), this forwards to
// arguments to MockingBitGen::Register.
//
// The underlying KeyT must match the KeyT constructed by DistributionCaller.
template <typename DistrT, typename Ret, typename... Args>
struct MockSingleOverload<DistrT, Ret(MockingBitGen&, Args...)> {
  static_assert(std::is_same<typename DistrT::result_type, Ret>::value,
                "Overload signature must have return type matching the "
                "distribution result_type.");
  using KeyT = Ret(DistrT, std::tuple<Args...>);
  auto gmock_Call(
      absl::MockingBitGen& gen,  // NOLINT(google-runtime-references)
      const ::testing::Matcher<Args>&... matchers)
      -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...)) {
    return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matchers...);
  }
};

template <typename DistrT, typename Ret, typename Arg, typename... Args>
struct MockSingleOverload<DistrT, Ret(Arg, MockingBitGen&, Args...)> {
  static_assert(std::is_same<typename DistrT::result_type, Ret>::value,
                "Overload signature must have return type matching the "
                "distribution result_type.");
  using KeyT = Ret(DistrT, std::tuple<Arg, Args...>);
  auto gmock_Call(
      const ::testing::Matcher<Arg>& matcher,
      absl::MockingBitGen& gen,  // NOLINT(google-runtime-references)
      const ::testing::Matcher<Args>&... matchers)
      -> decltype(MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher,
                                                             matchers...)) {
    return MockHelpers::MockFor<KeyT>(gen).gmock_Call(matcher, matchers...);
  }
};

// MockOverloadSet
//
// MockOverloadSet takes a distribution and a collection of signatures and
// performs overload resolution amongst all the overloads. This makes
// `EXPECT_CALL(mock_overload_set, Call(...))` expand and do overload resolution
// correctly.
template <typename DistrT, typename... Signatures>
struct MockOverloadSet;

template <typename DistrT, typename Sig>
struct MockOverloadSet<DistrT, Sig> : public MockSingleOverload<DistrT, Sig> {
  using MockSingleOverload<DistrT, Sig>::gmock_Call;
};

template <typename DistrT, typename FirstSig, typename... Rest>
struct MockOverloadSet<DistrT, FirstSig, Rest...>
    : public MockSingleOverload<DistrT, FirstSig>,
      public MockOverloadSet<DistrT, Rest...> {
  using MockSingleOverload<DistrT, FirstSig>::gmock_Call;
  using MockOverloadSet<DistrT, Rest...>::gmock_Call;
};

}  // namespace random_internal
ABSL_NAMESPACE_END
}  // namespace absl
#endif  // ABSL_RANDOM_INTERNAL_MOCK_OVERLOAD_SET_H_
