// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SRC_TINT_UTILS_MATH_HASH_H_
#define SRC_TINT_UTILS_MATH_HASH_H_

#include <stdint.h>

#include <cstdio>
#include <functional>
#include <optional>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>

#include "src/tint/utils/math/crc32.h"

namespace tint {
namespace detail {

template <typename T, typename = void>
struct HasHashCodeMember : std::false_type {};

template <typename T>
struct HasHashCodeMember<
    T,
    std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::HashCode)>>> : std::true_type {
};

}  // namespace detail

/// The type of a hash code
using HashCode = uint32_t;

/// Forward declarations (see below)
template <typename... ARGS>
HashCode Hash(const ARGS&... values);

template <typename... ARGS>
HashCode HashCombine(HashCode hash, const ARGS&... values);

/// A STL-compatible hasher that does a more thorough job than most implementations of std::hash.
/// Hasher has been optimized for a better quality hash at the expense of increased computation
/// costs.
/// Hasher is specialized for various core Tint data types. The default implementation will use a
/// `HashCode HashCode()` method on the `T` type, and will fallback to `std::hash<T>` if
/// `T::HashCode` is missing.
template <typename T>
struct Hasher {
    /// @param value the value to hash
    /// @returns a hash of the value
    HashCode operator()(const T& value) const {
        if constexpr (detail::HasHashCodeMember<T>::value) {
            auto hash = value.HashCode();
            static_assert(std::is_same_v<decltype(hash), HashCode>,
                          "T::HashCode() must return HashCode");
            return hash;
        } else {
            return static_cast<HashCode>(std::hash<T>()(value));
        }
    }
};

/// Hasher specialization for pointers
template <typename T>
struct Hasher<T*> {
    /// @param ptr the pointer to hash
    /// @returns a hash of the pointer
    HashCode operator()(T* ptr) const {
        auto hash = reinterpret_cast<uintptr_t>(ptr);
#ifdef TINT_HASH_SEED
        hash ^= static_cast<uint32_t>(TINT_HASH_SEED);
#endif
        if constexpr (sizeof(hash) > 4) {
            return static_cast<HashCode>(hash >> 4 | hash >> 32);
        } else {
            return static_cast<HashCode>(hash >> 4);
        }
    }
};

/// Hasher specialization for std::vector
template <typename T>
struct Hasher<std::vector<T>> {
    /// @param vector the vector to hash
    /// @returns a hash of the vector
    HashCode operator()(const std::vector<T>& vector) const {
        auto hash = Hash(vector.size());
        for (auto& el : vector) {
            hash = HashCombine(hash, el);
        }
        return hash;
    }
};

/// Hasher specialization for std::tuple
template <typename... TYPES>
struct Hasher<std::tuple<TYPES...>> {
    /// @param tuple the tuple to hash
    /// @returns a hash of the tuple
    HashCode operator()(const std::tuple<TYPES...>& tuple) const {
        return std::apply(Hash<TYPES...>, tuple);
    }
};

/// Hasher specialization for std::pair
template <typename A, typename B>
struct Hasher<std::pair<A, B>> {
    /// @param tuple the tuple to hash
    /// @returns a hash of the tuple
    HashCode operator()(const std::pair<A, B>& tuple) const {
        return std::apply(Hash<A, B>, tuple);
    }
};

/// Hasher specialization for std::optional
template <typename T>
struct Hasher<std::optional<T>> {
    /// @param optional the std::optional to hash
    /// @returns a hash of the std::optional
    HashCode operator()(const std::optional<T>& optional) const {
        auto hash = Hash(optional.has_value());
        if (optional.has_value()) {
            hash = HashCombine(hash, optional.value());
        }
        return hash;
    }
};

/// Hasher specialization for std::variant
template <typename... TYPES>
struct Hasher<std::variant<TYPES...>> {
    /// @param variant the variant to hash
    /// @returns a hash of the tuple
    HashCode operator()(const std::variant<TYPES...>& variant) const {
        return std::visit([](auto&& val) { return Hash(val); }, variant);
    }
};

/// Hasher specialization for std::string, which also supports hashing of const char* and
/// std::string_view without first constructing a std::string.
template <>
struct Hasher<std::string> {
    /// @param str the string to hash
    /// @returns a hash of the string
    HashCode operator()(const std::string& str) const {
        return static_cast<HashCode>(std::hash<std::string_view>()(std::string_view(str)));
    }

    /// @param str the string to hash
    /// @returns a hash of the string
    HashCode operator()(const char* str) const {
        return static_cast<HashCode>(std::hash<std::string_view>()(std::string_view(str)));
    }

    /// @param str the string to hash
    /// @returns a hash of the string
    HashCode operator()(const std::string_view& str) const {
        return static_cast<HashCode>(std::hash<std::string_view>()(str));
    }
};

/// Hasher specialization for std::unordered_map
template <typename K, typename V>
struct Hasher<std::unordered_map<K, V>> {
    /// @param map the std::unordered_map to hash
    /// @returns a hash of the map
    HashCode operator()(const std::unordered_map<K, V>& map) const {
        auto hash = Hash(map.size());
        for (const auto& [key, value] : map) {
            // Use an XOR to ensure that the non-deterministic ordering of the map still produces
            // the same hash value for the same entries.
            hash ^= Hash(key, value);
        }
        return hash;
    }
};

/// Hasher specialization for std::unordered_set
template <typename K>
struct Hasher<std::unordered_set<K>> {
    /// @param set the std::unordered_set to hash
    /// @returns a hash of the set
    HashCode operator()(const std::unordered_set<K>& set) const {
        auto hash = Hash(set.size());
        for (const auto& key : set) {
            // Use an XOR to ensure that the non-deterministic ordering of the map still produces
            // the same hash value for the same entries.
            hash ^= Hash(key);
        }
        return hash;
    }
};

/// @param args the arguments to hash
/// @returns a hash of the variadic list of arguments.
///          The returned hash is dependent on the order of the arguments.
template <typename... ARGS>
HashCode Hash(const ARGS&... args) {
    if constexpr (sizeof...(ARGS) == 0) {
        return 0;
    } else if constexpr (sizeof...(ARGS) == 1) {
        using T = std::tuple_element_t<0, std::tuple<ARGS...>>;
        return Hasher<T>()(args...);
    } else {
        HashCode hash = 102931;  // seed with an arbitrary prime
        return HashCombine(hash, args...);
    }
}

/// @param hash the hash value to combine with
/// @param values the values to hash
/// @returns a hash of the variadic list of arguments.
///          The returned hash is dependent on the order of the arguments.
template <typename... ARGS>
HashCode HashCombine(HashCode hash, const ARGS&... values) {
#ifdef TINT_HASH_SEED
    constexpr uint32_t offset = 0x7f4a7c16 ^ static_cast<uint32_t>(TINT_HASH_SEED);
#else
    constexpr uint32_t offset = 0x7f4a7c16;
#endif

    ((hash ^= Hash(values) + (offset ^ (hash >> 2))), ...);
    return hash;
}

/// A STL-compatible equal_to implementation that specializes for types.
template <typename T>
struct EqualTo {
    /// @param lhs the left hand side value
    /// @param rhs the right hand side value
    /// @returns true if the two values are equal
    constexpr bool operator()(const T& lhs, const T& rhs) const {
        return std::equal_to<T>()(lhs, rhs);
    }
};

/// A specialization for EqualTo for std::string, which supports additional comparision with
/// std::string_view and const char*.
template <>
struct EqualTo<std::string> {
    /// @param lhs the left hand side value
    /// @param rhs the right hand side value
    /// @returns true if the two values are equal
    bool operator()(const std::string& lhs, const std::string& rhs) const { return lhs == rhs; }

    /// @param lhs the left hand side value
    /// @param rhs the right hand side value
    /// @returns true if the two values are equal
    bool operator()(const std::string& lhs, const char* rhs) const { return lhs == rhs; }

    /// @param lhs the left hand side value
    /// @param rhs the right hand side value
    /// @returns true if the two values are equal
    bool operator()(const std::string& lhs, std::string_view rhs) const { return lhs == rhs; }

    /// @param lhs the left hand side value
    /// @param rhs the right hand side value
    /// @returns true if the two values are equal
    bool operator()(const char* lhs, const std::string& rhs) const { return lhs == rhs; }

    /// @param lhs the left hand side value
    /// @param rhs the right hand side value
    /// @returns true if the two values are equal
    bool operator()(std::string_view lhs, const std::string& rhs) const { return lhs == rhs; }
};

/// Wrapper for a hashable type enabling the wrapped value to be used as a key
/// for an unordered_map or unordered_set.
template <typename T>
struct UnorderedKeyWrapper {
    /// The wrapped value
    T value;
    /// The hash of value
    HashCode hash;

    /// Constructor
    /// @param v the value to wrap
    explicit UnorderedKeyWrapper(const T& v) : value(v), hash(Hash(v)) {}

    /// Move constructor
    /// @param v the value to wrap
    explicit UnorderedKeyWrapper(T&& v) : value(std::move(v)), hash(Hash(value)) {}

    /// @returns true if this wrapper comes before other
    /// @param other the RHS of the operator
    bool operator<(const UnorderedKeyWrapper& other) const { return hash < other.hash; }

    /// @returns true if this wrapped value is equal to the other wrapped value
    /// @param other the RHS of the operator
    bool operator==(const UnorderedKeyWrapper& other) const { return value == other.value; }
};

}  // namespace tint

namespace std {

/// Custom std::hash specialization for tint::UnorderedKeyWrapper
template <typename T>
class hash<tint::UnorderedKeyWrapper<T>> {
  public:
    /// @param w the UnorderedKeyWrapper
    /// @return the hash value
    inline std::size_t operator()(const tint::UnorderedKeyWrapper<T>& w) const { return w.hash; }
};

}  // namespace std

#endif  // SRC_TINT_UTILS_MATH_HASH_H_
