// 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.

#ifndef ABSL_HASH_HASH_TESTING_H_
#define ABSL_HASH_HASH_TESTING_H_

#include <initializer_list>
#include <tuple>
#include <type_traits>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/hash/internal/spy_hash_state.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/str_cat.h"
#include "absl/types/variant.h"

namespace absl {
inline namespace lts_2019_08_08 {

// Run the absl::Hash algorithm over all the elements passed in and verify that
// their hash expansion is congruent with their `==` operator.
//
// It is used in conjunction with EXPECT_TRUE. Failures will output information
// on what requirement failed and on which objects.
//
// Users should pass a collection of types as either an initializer list or a
// container of cases.
//
//   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
//       {v1, v2, ..., vN}));
//
//   std::vector<MyType> cases;
//   // Fill cases...
//   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(cases));
//
// Users can pass a variety of types for testing heterogeneous lookup with
// `std::make_tuple`:
//
//   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
//       std::make_tuple(v1, v2, ..., vN)));
//
//
// Ideally, the values passed should provide enough coverage of the `==`
// operator and the AbslHashValue implementations.
// For dynamically sized types, the empty state should usually be included in
// the values.
//
// The function accepts an optional comparator function, in case that `==` is
// not enough for the values provided.
//
// Usage:
//
//   EXPECT_TRUE(absl::VerifyTypeImplementsAbslHashCorrectly(
//       std::make_tuple(v1, v2, ..., vN), MyCustomEq{}));
//
// It checks the following requirements:
//   1. The expansion for a value is deterministic.
//   2. For any two objects `a` and `b` in the sequence, if `a == b` evaluates
//      to true, then their hash expansion must be equal.
//   3. If `a == b` evaluates to false their hash expansion must be unequal.
//   4. If `a == b` evaluates to false neither hash expansion can be a
//      suffix of the other.
//   5. AbslHashValue overloads should not be called by the user. They are only
//      meant to be called by the framework. Users should call H::combine() and
//      H::combine_contiguous().
//   6. No moved-from instance of the hash state is used in the implementation
//      of AbslHashValue.
//
// The values do not have to have the same type. This can be useful for
// equivalent types that support heterogeneous lookup.
//
// A possible reason for breaking (2) is combining state in the hash expansion
// that was not used in `==`.
// For example:
//
// struct Bad2 {
//   int a, b;
//   template <typename H>
//   friend H AbslHashValue(H state, Bad2 x) {
//     // Uses a and b.
//     return H::combine(std::move(state), x.a, x.b);
//   }
//   friend bool operator==(Bad2 x, Bad2 y) {
//     // Only uses a.
//     return x.a == y.a;
//   }
// };
//
// As for (3), breaking this usually means that there is state being passed to
// the `==` operator that is not used in the hash expansion.
// For example:
//
// struct Bad3 {
//   int a, b;
//   template <typename H>
//   friend H AbslHashValue(H state, Bad3 x) {
//     // Only uses a.
//     return H::combine(std::move(state), x.a);
//   }
//   friend bool operator==(Bad3 x, Bad3 y) {
//     // Uses a and b.
//     return x.a == y.a && x.b == y.b;
//   }
// };
//
// Finally, a common way to break 4 is by combining dynamic ranges without
// combining the size of the range.
// For example:
//
// struct Bad4 {
//   int *p, size;
//   template <typename H>
//   friend H AbslHashValue(H state, Bad4 x) {
//     return H::combine_contiguous(std::move(state), x.p, x.p + x.size);
//   }
//   friend bool operator==(Bad4 x, Bad4 y) {
//    // Compare two ranges for equality. C++14 code can instead use std::equal.
//     return absl::equal(x.p, x.p + x.size, y.p, y.p + y.size);
//   }
// };
//
// An easy solution to this is to combine the size after combining the range,
// like so:
// template <typename H>
// friend H AbslHashValue(H state, Bad4 x) {
//   return H::combine(
//       H::combine_contiguous(std::move(state), x.p, x.p + x.size), x.size);
// }
//
template <int&... ExplicitBarrier, typename Container>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(const Container& values);

template <int&... ExplicitBarrier, typename Container, typename Eq>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(const Container& values, Eq equals);

template <int&..., typename T>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(std::initializer_list<T> values);

template <int&..., typename T, typename Eq>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(std::initializer_list<T> values,
                                      Eq equals);

namespace hash_internal {

struct PrintVisitor {
  size_t index;
  template <typename T>
  std::string operator()(const T* value) const {
    return absl::StrCat("#", index, "(", testing::PrintToString(*value), ")");
  }
};

template <typename Eq>
struct EqVisitor {
  Eq eq;
  template <typename T, typename U>
  bool operator()(const T* t, const U* u) const {
    return eq(*t, *u);
  }
};

struct ExpandVisitor {
  template <typename T>
  SpyHashState operator()(const T* value) const {
    return SpyHashState::combine(SpyHashState(), *value);
  }
};

template <typename Container, typename Eq>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(const Container& values, Eq equals) {
  using V = typename Container::value_type;

  struct Info {
    const V& value;
    size_t index;
    std::string ToString() const {
      return absl::visit(PrintVisitor{index}, value);
    }
    SpyHashState expand() const { return absl::visit(ExpandVisitor{}, value); }
  };

  using EqClass = std::vector<Info>;
  std::vector<EqClass> classes;

  // Gather the values in equivalence classes.
  size_t i = 0;
  for (const auto& value : values) {
    EqClass* c = nullptr;
    for (auto& eqclass : classes) {
      if (absl::visit(EqVisitor<Eq>{equals}, value, eqclass[0].value)) {
        c = &eqclass;
        break;
      }
    }
    if (c == nullptr) {
      classes.emplace_back();
      c = &classes.back();
    }
    c->push_back({value, i});
    ++i;

    // Verify potential errors captured by SpyHashState.
    if (auto error = c->back().expand().error()) {
      return testing::AssertionFailure() << *error;
    }
  }

  if (classes.size() < 2) {
    return testing::AssertionFailure()
           << "At least two equivalence classes are expected.";
  }

  // We assume that equality is correctly implemented.
  // Now we verify that AbslHashValue is also correctly implemented.

  for (const auto& c : classes) {
    // All elements of the equivalence class must have the same hash
    // expansion.
    const SpyHashState expected = c[0].expand();
    for (const Info& v : c) {
      if (v.expand() != v.expand()) {
        return testing::AssertionFailure()
               << "Hash expansion for " << v.ToString()
               << " is non-deterministic.";
      }
      if (v.expand() != expected) {
        return testing::AssertionFailure()
               << "Values " << c[0].ToString() << " and " << v.ToString()
               << " evaluate as equal but have an unequal hash expansion.";
      }
    }

    // Elements from other classes must have different hash expansion.
    for (const auto& c2 : classes) {
      if (&c == &c2) continue;
      const SpyHashState c2_hash = c2[0].expand();
      switch (SpyHashState::Compare(expected, c2_hash)) {
        case SpyHashState::CompareResult::kEqual:
          return testing::AssertionFailure()
                 << "Values " << c[0].ToString() << " and " << c2[0].ToString()
                 << " evaluate as unequal but have an equal hash expansion.";
        case SpyHashState::CompareResult::kBSuffixA:
          return testing::AssertionFailure()
                 << "Hash expansion of " << c2[0].ToString()
                 << " is a suffix of the hash expansion of " << c[0].ToString()
                 << ".";
        case SpyHashState::CompareResult::kASuffixB:
          return testing::AssertionFailure()
                 << "Hash expansion of " << c[0].ToString()
                 << " is a suffix of the hash expansion of " << c2[0].ToString()
                 << ".";
        case SpyHashState::CompareResult::kUnequal:
          break;
      }
    }
  }
  return testing::AssertionSuccess();
}

template <typename... T>
struct TypeSet {
  template <typename U, bool = disjunction<std::is_same<T, U>...>::value>
  struct Insert {
    using type = TypeSet<U, T...>;
  };
  template <typename U>
  struct Insert<U, true> {
    using type = TypeSet;
  };

  template <template <typename...> class C>
  using apply = C<T...>;
};

template <typename... T>
struct MakeTypeSet : TypeSet<> {};
template <typename T, typename... Ts>
struct MakeTypeSet<T, Ts...> : MakeTypeSet<Ts...>::template Insert<T>::type {};

template <typename... T>
using VariantForTypes = typename MakeTypeSet<
    const typename std::decay<T>::type*...>::template apply<absl::variant>;

template <typename Container>
struct ContainerAsVector {
  using V = absl::variant<const typename Container::value_type*>;
  using Out = std::vector<V>;

  static Out Do(const Container& values) {
    Out out;
    for (const auto& v : values) out.push_back(&v);
    return out;
  }
};

template <typename... T>
struct ContainerAsVector<std::tuple<T...>> {
  using V = VariantForTypes<T...>;
  using Out = std::vector<V>;

  template <size_t... I>
  static Out DoImpl(const std::tuple<T...>& tuple, absl::index_sequence<I...>) {
    return Out{&std::get<I>(tuple)...};
  }

  static Out Do(const std::tuple<T...>& values) {
    return DoImpl(values, absl::index_sequence_for<T...>());
  }
};

template <>
struct ContainerAsVector<std::tuple<>> {
  static std::vector<VariantForTypes<int>> Do(std::tuple<>) { return {}; }
};

struct DefaultEquals {
  template <typename T, typename U>
  bool operator()(const T& t, const U& u) const {
    return t == u;
  }
};

}  // namespace hash_internal

template <int&..., typename Container>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(const Container& values) {
  return hash_internal::VerifyTypeImplementsAbslHashCorrectly(
      hash_internal::ContainerAsVector<Container>::Do(values),
      hash_internal::DefaultEquals{});
}

template <int&..., typename Container, typename Eq>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(const Container& values, Eq equals) {
  return hash_internal::VerifyTypeImplementsAbslHashCorrectly(
      hash_internal::ContainerAsVector<Container>::Do(values), equals);
}

template <int&..., typename T>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(std::initializer_list<T> values) {
  return hash_internal::VerifyTypeImplementsAbslHashCorrectly(
      hash_internal::ContainerAsVector<std::initializer_list<T>>::Do(values),
      hash_internal::DefaultEquals{});
}

template <int&..., typename T, typename Eq>
ABSL_MUST_USE_RESULT testing::AssertionResult
VerifyTypeImplementsAbslHashCorrectly(std::initializer_list<T> values,
                                      Eq equals) {
  return hash_internal::VerifyTypeImplementsAbslHashCorrectly(
      hash_internal::ContainerAsVector<std::initializer_list<T>>::Do(values),
      equals);
}

}  // inline namespace lts_2019_08_08
}  // namespace absl

#endif  // ABSL_HASH_HASH_TESTING_H_
