//
// 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_HELPERS_H_
#define ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_

#include <optional>
#include <utility>

#include "absl/base/config.h"
#include "absl/base/fast_type_id.h"
#include "absl/random/mocking_access.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {

// A no-op validator meeting the ValidatorT requirements for MockHelpers.
//
// Custom validators should follow a similar structure, passing the type to
// MockHelpers::MockFor<KeyT>(m, CustomValidatorT()).
struct NoOpValidator {
  // Default validation: do nothing.
  template <typename ResultT, typename... Args>
  static void Validate(ResultT, Args&&...) {}
};

// MockHelpers works in conjunction with MockOverloadSet, MockingBitGen, and
// BitGenRef to enable the mocking capability for absl distribution functions.
//
// MockingBitGen registers mocks based on the typeid of a mock signature, KeyT,
// which is used to generate a unique id.
//
// KeyT is a signature of the form:
//   result_type(discriminator_type, std::tuple<args...>)
// The mocked function signature will be composed from KeyT as:
//   result_type(args...)
//
class MockHelpers {
  using IdType = ::absl::FastTypeIdType;
  using RandomMockingAccess = ::absl::RandomMockingAccess;

  // Given a key signature type used to index the mock, extract the components.
  // KeyT is expected to have the form:
  //   result_type(discriminator_type, arg_tuple_type)
  template <typename KeyT>
  struct KeySignature;

  template <typename ResultT, typename DiscriminatorT, typename ArgTupleT>
  struct KeySignature<ResultT(DiscriminatorT, ArgTupleT)> {
    using result_type = ResultT;
    using discriminator_type = DiscriminatorT;
    using arg_tuple_type = ArgTupleT;
  };

 public:
  // Invoke a mock for the KeyT (may or may not be a signature).
  //
  // KeyT is used to generate a typeid-based lookup key for the mock.
  // KeyT is a signature of the form:
  //   result_type(discriminator_type, std::tuple<args...>)
  // The mocked function signature will be composed from KeyT as:
  //   result_type(args...)
  //
  // An instance of arg_tuple_type must be constructable from Args..., since
  // the underlying mechanism requires a pointer to an argument tuple.
  template <typename KeyT, typename URBG, typename... Args>
  static auto MaybeInvokeMock(URBG* urbg, Args&&... args)
      -> std::optional<typename KeySignature<KeyT>::result_type> {
    if constexpr (RandomMockingAccess::HasInvokeMock<URBG>::value) {
      typename KeySignature<KeyT>::arg_tuple_type arg_tuple(
          std::forward<Args>(args)...);
      typename KeySignature<KeyT>::result_type result;
      if (RandomMockingAccess::InvokeMock(urbg, FastTypeId<KeyT>(), &arg_tuple,
                                          &result)) {
        return result;
      }
    }
    return std::nullopt;
  }

  // Acquire a mock for the KeyT (may or may not be a signature), set up to use
  // the ValidatorT to verify that the result is in the range of the RNG
  // function.
  //
  // KeyT is used to generate a typeid-based lookup for the mock.
  // KeyT is a signature of the form:
  //   result_type(discriminator_type, std::tuple<args...>)
  // The mocked function signature will be composed from KeyT as:
  //   result_type(args...)
  // ValidatorT::Validate will be called after the result of the RNG. The
  //   signature is expected to be of the form:
  //      ValidatorT::Validate(result, args...)
  template <typename KeyT, typename ValidatorT, typename MockURBG>
  static auto MockFor(MockURBG& m, ValidatorT)
      -> decltype(m.template RegisterMock<
                  typename KeySignature<KeyT>::result_type,
                  typename KeySignature<KeyT>::arg_tuple_type>(
          m, std::declval<IdType>(), ValidatorT())) {
    return m.template RegisterMock<typename KeySignature<KeyT>::result_type,
                                   typename KeySignature<KeyT>::arg_tuple_type>(
        m, ::absl::FastTypeId<KeyT>(), ValidatorT());
  }

  // Acquire a mock for the KeyT (may or may not be a signature).
  //
  // KeyT is used to generate a typeid-based lookup for the mock.
  // KeyT is a signature of the form:
  //   result_type(discriminator_type, std::tuple<args...>)
  // The mocked function signature will be composed from KeyT as:
  //   result_type(args...)
  template <typename KeyT, typename MockURBG>
  static decltype(auto) MockFor(MockURBG& m) {
    return MockFor<KeyT>(m, NoOpValidator());
  }
};

}  // namespace random_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_RANDOM_INTERNAL_MOCK_HELPERS_H_
