// Copyright 2022 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_CONTAINERS_HASHMAP_BASE_H_
#define SRC_TINT_UTILS_CONTAINERS_HASHMAP_BASE_H_

#include <algorithm>
#include <functional>
#include <optional>
#include <tuple>
#include <utility>

#include "src/tint/utils/containers/vector.h"
#include "src/tint/utils/ice/ice.h"
#include "src/tint/utils/math/hash.h"
#include "src/tint/utils/math/math.h"
#include "src/tint/utils/traits/traits.h"

namespace tint {

/// HashmapKey wraps the comparator type for a Hashmap and Hashset.
/// HashmapKey acts like a read-only `T`, but can be reassigned so long as the value is equivalent.
/// @tparam T the key comparator type.
/// @tparam HASH the hash function for the key type.
/// @tparam EQUAL the equality function for the key type.
template <typename T, typename HASH = Hasher<T>, typename EQUAL = std::equal_to<T>>
class HashmapKey {
    T value_;

  public:
    /// Key is an alias to this templated class.
    using Key = HashmapKey<T, HASH, EQUAL>;
    /// Hash is an alias to the hash function for the key type.
    using Hash = HASH;
    /// Equal is an alias to the equality function for the key type.
    using Equal = EQUAL;

    /// KeyOf() returns @p key, so a HashmapKey can be used as the entry type for a Hashset.
    /// @param key the HashmapKey
    /// @return @p key
    static const Key& KeyOf(const Key& key) { return key; }

    /// Constructor using copied value.
    /// @param value the key value.
    HashmapKey(const T& value) : value_(value), hash(HASH{}(value_)) {}  // NOLINT

    /// Constructor using moved value.
    /// @param value the key value.
    HashmapKey(T&& value) : value_(std::forward<T>(value)), hash(HASH{}(value_)) {}  // NOLINT

    /// Constructor using pre-computed hash and copied value.
    /// @param hash_ the precomputed hash of @p value
    /// @param value the key value
    HashmapKey(size_t hash_, const T& value) : value_(value), hash(hash_) {}

    /// Constructor using pre-computed hash and moved value.
    /// @param hash_ the precomputed hash of @p value
    /// @param value the key value
    HashmapKey(size_t hash_, T&& value) : value_(std::forward<T>(value)), hash(hash_) {}

    /// Copy constructor
    HashmapKey(const HashmapKey&) = default;

    /// Move constructor
    HashmapKey(HashmapKey&&) = default;

    /// Destructor
    ~HashmapKey() = default;

    /// Copy-assignment operator.
    /// @note As a hashmap uses the HashmapKey for indexing, the new value *must* have the same hash
    /// value and be equal to this key.
    /// @param other the key to copy to this key.
    /// @return this HashmapKey.
    HashmapKey& operator=(const HashmapKey& other) {
        TINT_ASSERT(*this == other);
        value_ = other.Value();
        return *this;
    }

    /// Move-assignment operator.
    /// @note As a hashmap uses the HashmapKey for indexing, the new value *must* have the same hash
    /// value and be equal to this key.
    /// @param other the key to move to this key.
    /// @return this HashmapKey.
    HashmapKey& operator=(HashmapKey&& other) {
        TINT_ASSERT(*this == other);
        value_ = std::move(other.Value());
        return *this;
    }

    /// Equality operator
    /// @param other the other key.
    /// @return true if the hash and value of @p other are equal to this key.
    bool operator==(const HashmapKey& other) const {
        return hash == other.hash && EQUAL{}(value_, other.Value());
    }

    /// Equality operator
    /// @param other the other key.
    /// @return true if the hash of other and value of @p other are equal to this key.
    template <typename RHS>
    bool operator==(const RHS& other) const {
        return hash == HASH{}(other) && EQUAL{}(value_, other);
    }

    /// @returns the value of the key
    const T& Value() const { return value_; }

    /// @returns the value of the key
    operator const T&() const { return value_; }

    /// @returns the pointer to the value, or the value itself if T is a pointer.
    auto operator->() const {
        if constexpr (std::is_pointer_v<T>) {
            // operator-> is useless if the T is a pointer, so automatically unwrap a pointer.
            return value_;
        } else {
            return &value_;
        }
    }

    /// The hash of value
    const size_t hash;
};

/// Writes the HashmapKey to the stream.
/// @param out the stream to write to
/// @param key the HashmapKey to write
/// @returns out so calls can be chained
template <typename STREAM, typename T, typename = traits::EnableIfIsOStream<STREAM>>
auto& operator<<(STREAM& out, const HashmapKey<T>& key) {
    if constexpr (traits::HasOperatorShiftLeft<STREAM, T>) {
        return out << key.Value();
    } else {
        return out << "<hashmap-key>";
    }
}

/// HashmapBase is the base class for Hashmap and Hashset.
/// @tparam ENTRY is the single record in the map. The entry type must alias 'Key' to the HashmapKey
/// type, and implement the method `static HashmapKey<...> KeyOf(ENTRY)` to return the key for the
/// entry.
template <typename ENTRY, size_t N>
class HashmapBase {
  protected:
    struct Node;
    struct Slot;

  public:
    /// Entry is the type of a single record in the hashmap.
    using Entry = ENTRY;
    /// Key is the HashmapKey type used to find entries.
    using Key = typename Entry::Key;
    /// Hash is the
    using Hash = typename Key::Hash;
    /// Equal is the
    using Equal = typename Key::Equal;

    /// The minimum capacity of the map.
    static constexpr size_t kMinCapacity = std::max<size_t>(N, 8);

    /// The target number of slots, expressed as a fractional percentage of the map capacity.
    /// e.g. a kLoadFactor of 75, would mean a target slots count of (0.75 * capacity).
    static constexpr size_t kLoadFactor = 75;

    /// @param capacity the capacity of the map, as total number of entries.
    /// @returns the target slot vector size to hold @p capacity map entries.
    static constexpr size_t NumSlots(size_t capacity) {
        return (std::max<size_t>(capacity, kMinCapacity) * kLoadFactor) / 100;
    }

    /// Constructor.
    /// Constructs an empty map.
    HashmapBase() {
        slots_.Resize(slots_.Capacity());
        for (auto& node : fixed_) {
            free_.Add(&node);
        }
    }

    /// Copy constructor.
    /// Constructs a map with a copy of @p other.
    /// @param other the map to copy.
    HashmapBase(const HashmapBase& other) : HashmapBase() {
        if (&other != this) {
            Copy(other);
        }
    }

    /// Move constructor.
    /// Constructs a map with the moved entries of @p other.
    /// @param other the map to move.
    HashmapBase(HashmapBase&& other) : HashmapBase() {
        if (&other != this) {
            Move(std::move(other));
        }
    }

    /// Destructor.
    ~HashmapBase() {
        // Call the destructor on all entries in the map.
        for (size_t slot_idx = 0; slot_idx < slots_.Length(); slot_idx++) {
            auto* node = slots_[slot_idx].nodes;
            while (node) {
                auto next = node->next;
                node->Destroy();
                node = next;
            }
        }
    }

    /// Assignment operator.
    /// Clears this map, and populates this map with a copy of @p other.
    /// @param other the map to copy.
    /// @returns this HashmapBase
    HashmapBase& operator=(const HashmapBase& other) {
        if (&other != this) {
            Clear();
            Copy(other);
        }
        return *this;
    }

    /// Move-assignment operator.
    /// Clears this map, and populates this map with the moved entries of @p other.
    /// @param other the map to move.
    /// @returns this HashmapBase
    HashmapBase& operator=(HashmapBase&& other) {
        if (&other != this) {
            Clear();
            Move(std::move(other));
        }
        return *this;
    }

    /// @returns the number of entries in the map.
    size_t Count() const { return count_; }

    /// @returns true if the map holds no entries.
    bool IsEmpty() const { return count_ == 0; }

    /// Removes all the entries from the map.
    /// @note the map's capacity is not reduced, as it is assumed that a reused map will likely fill
    /// to a similar size as before.
    void Clear() {
        for (size_t slot_idx = 0; slot_idx < slots_.Length(); slot_idx++) {
            auto* node = slots_[slot_idx].nodes;
            while (node) {
                auto next = node->next;
                node->Destroy();
                free_.Add(node);
                node = next;
            }
            slots_[slot_idx].nodes = nullptr;
        }
    }

    /// Ensures that the map can hold @p n entries without heap reallocation or rehashing.
    /// @param n the number of entries to ensure can fit in the map without reallocation or
    /// rehashing.
    void Reserve(size_t n) {
        if (n > capacity_) {
            size_t count = n - capacity_;
            free_.Allocate(count);
            capacity_ += count;
        }
    }

    /// Looks up an entry with the given key.
    /// @param key the entry's key to search for.
    /// @returns a pointer to the matching entry, or null if no entry was found.
    /// @note The returned pointer is guaranteed to be valid until the owning entry is removed,
    /// the map is cleared, or the map is destructed.
    template <typename K>
    Entry* GetEntry(K&& key) {
        size_t hash = Hash{}(key);
        auto& slot = slots_[hash % slots_.Length()];
        return slot.Find(hash, key);
    }

    /// Looks up an entry with the given key.
    /// @param key the entry's key to search for.
    /// @returns a pointer to the matching entry, or null if no entry was found.
    /// @note The returned pointer is guaranteed to be valid until the owning entry is removed,
    /// the map is cleared, or the map is destructed.
    template <typename K>
    const Entry* GetEntry(K&& key) const {
        size_t hash = Hash{}(key);
        auto& slot = slots_[hash % slots_.Length()];
        return slot.Find(hash, key);
    }

    /// @returns true if the map contains an entry with a key that matches @p key.
    /// @param key the key to look for.
    template <typename K = Key>
    bool Contains(K&& key) const {
        return GetEntry(key) != nullptr;
    }

    /// Removes an entry from the map that has a key which matches @p key.
    /// @returns true if the entry was found and removed, otherwise false.
    /// @param key the key to look for.
    template <typename K = Key>
    bool Remove(K&& key) {
        size_t hash = Hash{}(key);
        auto& slot = slots_[hash % slots_.Length()];
        Node** edge = &slot.nodes;
        for (auto* node = *edge; node; node = node->next) {
            if (node->Equals(hash, key)) {
                *edge = node->next;
                node->Destroy();
                free_.Add(node);
                count_--;
                return true;
            }
            edge = &node->next;
        }
        return false;
    }

    /// Iterator for entries in the map.
    template <bool IS_CONST>
    class IteratorT {
      private:
        using MAP = std::conditional_t<IS_CONST, const HashmapBase, HashmapBase>;
        using NODE = std::conditional_t<IS_CONST, const Node, Node>;

      public:
        /// @returns the entry pointed to by this iterator
        auto& operator->() { return node_->Entry(); }

        /// @returns a reference to the entry at the iterator
        auto& operator*() { return node_->Entry(); }

        /// Increments the iterator
        /// @returns this iterator
        IteratorT& operator++() {
            node_ = node_->next;
            SkipEmptySlots();
            return *this;
        }

        /// Equality operator
        /// @param other the other iterator to compare this iterator to
        /// @returns true if this iterator is equal to other
        bool operator==(const IteratorT& other) const { return node_ == other.node_; }

        /// Inequality operator
        /// @param other the other iterator to compare this iterator to
        /// @returns true if this iterator is not equal to other
        bool operator!=(const IteratorT& other) const { return node_ != other.node_; }

      private:
        /// Friend class
        friend class HashmapBase;

        IteratorT(MAP& map, size_t slot, NODE* node) : map_(map), slot_(slot), node_(node) {
            SkipEmptySlots();
        }

        void SkipEmptySlots() {
            while (!node_ && slot_ + 1 < map_.slots_.Length()) {
                node_ = map_.slots_[++slot_].nodes;
            }
        }

        MAP& map_;
        size_t slot_ = 0;
        NODE* node_ = nullptr;
    };

    /// An immutable key and mutable value iterator
    using Iterator = IteratorT</*IS_CONST*/ false>;

    /// An immutable key and value iterator
    using ConstIterator = IteratorT</*IS_CONST*/ true>;

    /// @returns an immutable iterator to the start of the map.
    ConstIterator begin() const { return ConstIterator{*this, 0, slots_.Front().nodes}; }

    /// @returns an immutable iterator to the end of the map.
    ConstIterator end() const { return ConstIterator{*this, slots_.Length(), nullptr}; }

    /// @returns an iterator to the start of the map.
    Iterator begin() { return Iterator{*this, 0, slots_.Front().nodes}; }

    /// @returns an iterator to the end of the map.
    Iterator end() { return Iterator{*this, slots_.Length(), nullptr}; }

    /// STL-friendly alias to Entry. Used by gmock.
    using value_type = const Entry&;

  protected:
    /// Node holds an Entry in a linked list.
    struct Node {
        /// A structure that has the same size and alignment as Entry.
        /// Replacement for std::aligned_storage as this is broken on earlier versions of MSVC.
        struct alignas(alignof(ENTRY)) Storage {
            /// Byte array of length sizeof(ENTRY)
            uint8_t data[sizeof(ENTRY)];
        };

        /// Destructs the entry.
        void Destroy() { Entry().~ENTRY(); }

        /// @returns the storage reinterpreted as an `Entry&`
        ENTRY& Entry() { return *Bitcast<ENTRY*>(&storage.data[0]); }

        /// @returns the storage reinterpreted as a `const Entry&`
        const ENTRY& Entry() const { return *Bitcast<const ENTRY*>(&storage.data[0]); }

        /// @returns a reference to the Entry's HashmapKey
        const HashmapBase::Key& Key() const { return HashmapBase::Entry::KeyOf(Entry()); }

        /// @param hash the hash value to compare against the Entry's key hash value
        /// @param value the value to compare against the Entry's key
        /// @returns true if the Entry's hash is equal to @p hash, and the Entry's key is equal to
        /// @p value.
        template <typename T>
        bool Equals(size_t hash, T&& value) const {
            auto& key = Key();
            return key.hash == hash && HashmapBase::Equal{}(key.Value(), value);
        }

        /// storage is a buffer that has the same size and alignment as Entry.
        /// The storage holds a constructed Entry when linked in the slots, and is destructed when
        /// removed from slots.
        Storage storage;

        /// next is the next Node in the slot, or in the free list.
        Node* next;
    };

    /// Copies the hashmap @p other into this empty hashmap.
    /// @note This hashmap must be empty before calling
    /// @param other the hashmap to copy
    void Copy(const HashmapBase& other) {
        Reserve(other.capacity_);
        slots_.Resize(other.slots_.Length());
        for (size_t slot_idx = 0; slot_idx < slots_.Length(); slot_idx++) {
            for (auto* o = other.slots_[slot_idx].nodes; o; o = o->next) {
                auto* node = free_.Take();
                new (&node->Entry()) Entry{o->Entry()};
                slots_[slot_idx].Add(node);
            }
        }
        count_ = other.count_;
    }

    /// Moves the the hashmap @p other into this empty hashmap.
    /// @note This hashmap must be empty before calling
    /// @param other the hashmap to move
    void Move(HashmapBase&& other) {
        Reserve(other.capacity_);
        slots_.Resize(other.slots_.Length());
        for (size_t slot_idx = 0; slot_idx < slots_.Length(); slot_idx++) {
            for (auto* o = other.slots_[slot_idx].nodes; o; o = o->next) {
                auto* node = free_.Take();
                new (&node->Entry()) Entry{std::move(o->Entry())};
                slots_[slot_idx].Add(node);
            }
        }
        count_ = other.count_;
        other.Clear();
    }

    /// EditIndex is the structure returned by EditAt(), used to simplify entry replacement and
    /// insertion.
    struct EditIndex {
        /// The HashmapBase that created this EditIndex
        HashmapBase& map;
        /// The slot that will hold the edit.
        Slot& slot;
        /// The hash of the key, passed to EditAt().
        size_t hash;
        /// The resolved node entry, or nullptr if EditAt() did not resolve to an existing entry.
        Entry* entry = nullptr;

        /// Replace will replace the entry with a new Entry built from @p key and @p values.
        /// @note #entry must not be null before calling.
        /// @note the new key must have equality to the old key.
        /// @param key the key value (inner value of a HashmapKey).
        /// @param values optional additional values to pass to the Entry constructor.
        template <typename K, typename... V>
        void Replace(K&& key, V&&... values) {
            *entry = Entry{Key{hash, std::forward<K>(key)}, std::forward<V>(values)...};
        }

        /// Insert will create a new entry using @p key and @p values and insert it into the slot.
        /// The created entry will be assigned to #entry before returning.
        /// @note #entry must be null before calling.
        /// @note the key must not already exist in the map.
        /// @param key the key value (inner value of a HashmapKey).
        /// @param values optional additional values to pass to the Entry constructor.
        template <typename K, typename... V>
        void Insert(K&& key, V&&... values) {
            auto* node = map.free_.Take();
            slot.Add(node);
            map.count_++;
            entry = &node->Entry();
            new (entry) Entry{Key{hash, std::forward<K>(key)}, std::forward<V>(values)...};
        }
    };

    /// EditAt is a helper for map entry replacement and entry insertion.
    /// Before indexing, EditAt will ensure there's at least one free node available, potentially
    /// allocating and rehashing if there's no free nodes available.
    /// @param key the key used to compute the hash, look up the slot and search for the existing
    /// node.
    /// @returns a EditIndex used to modify or insert a new entry into the map with the given key.
    template <typename K>
    EditIndex EditAt(K&& key) {
        if (!free_.nodes_) {
            free_.Allocate(capacity_);
            capacity_ += capacity_;
            Rehash();
        }
        size_t hash = Hash{}(key);
        auto& slot = slots_[hash % slots_.Length()];
        auto* entry = slot.Find(hash, key);
        return {*this, slot, hash, entry};
    }

    /// Rehash resizes the slots vector proportionally to the map capacity, and then reinserts the
    /// nodes so they're linked in the correct slots linked lists.
    void Rehash() {
        size_t num_slots = NumSlots(capacity_);
        decltype(slots_) old_slots;
        std::swap(slots_, old_slots);
        slots_.Resize(num_slots);
        for (size_t old_slot_idx = 0; old_slot_idx < old_slots.Length(); old_slot_idx++) {
            auto* node = old_slots[old_slot_idx].nodes;
            while (node) {
                auto next = node->next;
                size_t new_slot_idx = node->Key().hash % num_slots;
                slots_[new_slot_idx].Add(node);
                node = next;
            }
        }
    }

    /// Slot holds a linked list of nodes. Nodes are assigned to the slot list by calculating the
    /// modulo of the entry's hash with the slot_ vector length.
    struct Slot {
        /// The linked list of nodes in this slot.
        Node* nodes = nullptr;

        /// Add adds the node @p node to this slot.
        /// @note The node must be unlinked from any existing list before calling.
        /// @param node the node to add.
        void Add(Node* node) {
            node->next = nodes;
            nodes = node;
        }

        /// @returns the node in the slot with the given hash and key.
        /// @param hash the key hash to search for.
        /// @param key the key value to search for.
        template <typename K>
        const Entry* Find(size_t hash, K&& key) const {
            for (auto* node = nodes; node; node = node->next) {
                if (node->Equals(hash, key)) {
                    return &node->Entry();
                }
            }
            return nullptr;
        }

        /// @returns the node in the slot with the given hash and key.
        /// @param hash the key hash to search for.
        /// @param key the key value to search for.
        template <typename K>
        Entry* Find(size_t hash, K&& key) {
            for (auto* node = nodes; node; node = node->next) {
                if (node->Equals(hash, key)) {
                    return &node->Entry();
                }
            }
            return nullptr;
        }
    };

    /// Free holds a linked list of nodes which are currently not used by entries in the map, and a
    /// linked list of node allocations.
    struct FreeNodes {
        /// Allocation is the header of a block of memory that holds Nodes.
        struct Allocation {
            /// The linked list of allocations.
            Allocation* next = nullptr;
            // Node[] array follows this structure.
        };

        /// The linked list of free nodes.
        Node* nodes_ = nullptr;

        /// The linked list of allocations.
        Allocation* allocations_ = nullptr;

        /// Destructor.
        /// Frees all the allocations made.
        ~FreeNodes() {
            auto* allocation = allocations_;
            while (allocation) {
                auto* next = allocation->next;
                free(allocation);
                allocation = next;
            }
        }

        /// @returns the next free node in the list
        Node* Take() {
            auto* node = nodes_;
            nodes_ = node->next;
            node->next = nullptr;
            return node;
        }

        /// Add adds the node @p node to the list of free nodes.
        /// @note The node must be unlinked from any existing list before calling.
        /// @param node the node to add.
        void Add(Node* node) {
            node->next = nodes_;
            nodes_ = node;
        }

        /// Allocate allocates an additional @p count nodes and adds them to the free node list.
        /// @param count the number of new nodes to allocate.
        /// @note callers must remember to increment HashmapBase::capacity_ by the same amount.
        void Allocate(size_t count) {
            static_assert(std::is_trivial_v<Node>,
                          "Node is not trivial, and will require construction / destruction");
            constexpr size_t kAllocationSize = RoundUp(alignof(Node), sizeof(Allocation));
            auto* memory =
                reinterpret_cast<std::byte*>(malloc(kAllocationSize + sizeof(Node) * count));
            if (TINT_UNLIKELY(!memory)) {
                TINT_ICE() << "out of memory";
                return;
            }
            auto* nodes_allocation = Bitcast<Allocation*>(memory);
            nodes_allocation->next = allocations_;
            allocations_ = nodes_allocation;

            auto* nodes = Bitcast<Node*>(memory + kAllocationSize);
            for (size_t i = 0; i < count; i++) {
                Add(&nodes[i]);
            }
        }
    };

    /// The fixed-size array of nodes, used for the first kMinCapacity entries of the map, before
    /// allocating from the heap.
    std::array<Node, kMinCapacity> fixed_;
    /// The vector of slots. Each slot holds a linked list of nodes which hold entries in the map.
    Vector<Slot, NumSlots(N)> slots_;
    /// The linked list of free nodes, and node allocations from the heap.
    FreeNodes free_;
    /// The total number of nodes, including free nodes (kMinCapacity + heap-allocated)
    size_t capacity_ = kMinCapacity;
    /// The total number of nodes that currently hold map entries.
    size_t count_ = 0;
};

}  // namespace tint

#endif  // SRC_TINT_UTILS_CONTAINERS_HASHMAP_BASE_H_
