// Copyright 2018 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.
//
// -----------------------------------------------------------------------------
// mocking_bit_gen.h
// -----------------------------------------------------------------------------
//
// This file includes an `absl::MockingBitGen` class to use as a mock within the
// Googletest testing framework. Such a mock is useful to provide deterministic
// values as return values within (otherwise random) Abseil distribution
// functions. Such determinism within a mock is useful within testing frameworks
// to test otherwise indeterminate APIs.
//
// More information about the Googletest testing framework is available at
// https://github.com/google/googletest

#ifndef ABSL_RANDOM_MOCKING_BIT_GEN_H_
#define ABSL_RANDOM_MOCKING_BIT_GEN_H_

#include <iterator>
#include <limits>
#include <memory>
#include <tuple>
#include <type_traits>
#include <typeindex>
#include <typeinfo>
#include <utility>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/container/flat_hash_map.h"
#include "absl/meta/type_traits.h"
#include "absl/random/distributions.h"
#include "absl/random/internal/distribution_caller.h"
#include "absl/random/internal/mocking_bit_gen_base.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include "absl/types/span.h"
#include "absl/types/variant.h"
#include "absl/utility/utility.h"

namespace absl {
ABSL_NAMESPACE_BEGIN

namespace random_internal {

template <typename, typename>
struct MockSingleOverload;

}  // namespace random_internal

// MockingBitGen
//
// `absl::MockingBitGen` is a mock Uniform Random Bit Generator (URBG) class
// which can act in place of an `absl::BitGen` URBG within tests using the
// Googletest testing framework.
//
// Usage:
//
// Use an `absl::MockingBitGen` along with a mock distribution object (within
// mock_distributions.h) inside Googletest constructs such as ON_CALL(),
// EXPECT_TRUE(), etc. to produce deterministic results conforming to the
// distribution's API contract.
//
// Example:
//
//  // Mock a call to an `absl::Bernoulli` distribution using Googletest
//   absl::MockingBitGen bitgen;
//
//   ON_CALL(absl::MockBernoulli(), Call(bitgen, 0.5))
//       .WillByDefault(testing::Return(true));
//   EXPECT_TRUE(absl::Bernoulli(bitgen, 0.5));
//
//  // Mock a call to an `absl::Uniform` distribution within Googletest
//  absl::MockingBitGen bitgen;
//
//   ON_CALL(absl::MockUniform<int>(), Call(bitgen, testing::_, testing::_))
//       .WillByDefault([] (int low, int high) {
//           return (low + high) / 2;
//       });
//
//   EXPECT_EQ(absl::Uniform<int>(gen, 0, 10), 5);
//   EXPECT_EQ(absl::Uniform<int>(gen, 30, 40), 35);
//
// At this time, only mock distributions supplied within the Abseil random
// library are officially supported.
//
class MockingBitGen : public absl::random_internal::MockingBitGenBase {
 public:
  MockingBitGen() {}

  ~MockingBitGen() override;

 private:
  template <typename DistrT, typename... Args>
  using MockFnType =
      ::testing::MockFunction<typename DistrT::result_type(Args...)>;

  // MockingBitGen::Register
  //
  // Register<DistrT, FormatT, ArgTupleT> is the main extension point for
  // extending the MockingBitGen framework. It provides a mechanism to install a
  // mock expectation for the distribution `distr_t` onto the MockingBitGen
  // context.
  //
  // The returned MockFunction<...> type can be used to setup additional
  // distribution parameters of the expectation.
  template <typename DistrT, typename... Args, typename... Ms>
  decltype(std::declval<MockFnType<DistrT, Args...>>().gmock_Call(
      std::declval<Ms>()...))
  Register(Ms&&... matchers) {
    auto& mock =
        mocks_[std::type_index(GetTypeId<DistrT, std::tuple<Args...>>())];

    if (!mock.mock_fn) {
      auto* mock_fn = new MockFnType<DistrT, Args...>;
      mock.mock_fn = mock_fn;
      mock.match_impl = &MatchImpl<DistrT, Args...>;
      deleters_.emplace_back([mock_fn] { delete mock_fn; });
    }

    return static_cast<MockFnType<DistrT, Args...>*>(mock.mock_fn)
        ->gmock_Call(std::forward<Ms>(matchers)...);
  }

  mutable std::vector<std::function<void()>> deleters_;

  using match_impl_fn = void (*)(void* mock_fn, void* t_erased_dist_args,
                                 void* t_erased_result);
  struct MockData {
    void* mock_fn = nullptr;
    match_impl_fn match_impl = nullptr;
  };

  mutable absl::flat_hash_map<std::type_index, MockData> mocks_;

  template <typename DistrT, typename... Args>
  static void MatchImpl(void* mock_fn, void* dist_args, void* result) {
    using result_type = typename DistrT::result_type;
    *static_cast<result_type*>(result) = absl::apply(
        [mock_fn](Args... args) -> result_type {
          return (*static_cast<MockFnType<DistrT, Args...>*>(mock_fn))
              .Call(std::move(args)...);
        },
        *static_cast<std::tuple<Args...>*>(dist_args));
  }

  // Looks for an appropriate mock - Returns the mocked result if one is found.
  // Otherwise, returns a random value generated by the underlying URBG.
  bool CallImpl(const std::type_info& key_type, void* dist_args,
                void* result) override {
    // Trigger a mock, if there exists one that matches `param`.
    auto it = mocks_.find(std::type_index(key_type));
    if (it == mocks_.end()) return false;
    auto* mock_data = static_cast<MockData*>(&it->second);
    mock_data->match_impl(mock_data->mock_fn, dist_args, result);
    return true;
  }

  template <typename, typename>
  friend struct ::absl::random_internal::MockSingleOverload;
  friend struct ::absl::random_internal::DistributionCaller<
      absl::MockingBitGen>;
};

// -----------------------------------------------------------------------------
// Implementation Details Only Below
// -----------------------------------------------------------------------------

namespace random_internal {

template <>
struct DistributionCaller<absl::MockingBitGen> {
  template <typename DistrT, typename FormatT, typename... Args>
  static typename DistrT::result_type Call(absl::MockingBitGen* gen,
                                           Args&&... args) {
    return gen->template Call<DistrT, FormatT>(std::forward<Args>(args)...);
  }
};

}  // namespace random_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_RANDOM_MOCKING_BIT_GEN_H_
