// Copyright 2020 The Dawn 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
//
//     http://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 DAWNNATIVE_OBJECT_CONTENT_HASHER_H_
#define DAWNNATIVE_OBJECT_CONTENT_HASHER_H_

#include "dawn/common/HashUtils.h"

#include <string>
#include <vector>

namespace dawn::native {

    // ObjectContentHasher records a hash that can be used as a key to lookup a cached object in a
    // cache.
    class ObjectContentHasher {
      public:
        // Record calls the appropriate record function based on the type.
        template <typename T, typename... Args>
        void Record(const T& value, const Args&... args) {
            RecordImpl<T, Args...>::Call(this, value, args...);
        }

        size_t GetContentHash() const;

      private:
        template <typename T, typename... Args>
        struct RecordImpl {
            static constexpr void Call(ObjectContentHasher* recorder,
                                       const T& value,
                                       const Args&... args) {
                HashCombine(&recorder->mContentHash, value, args...);
            }
        };

        template <typename T>
        struct RecordImpl<T*> {
            static constexpr void Call(ObjectContentHasher* recorder, T* obj) {
                // Calling Record(objPtr) is not allowed. This check exists to only prevent such
                // mistakes.
                static_assert(obj == nullptr);
            }
        };

        template <typename T>
        struct RecordImpl<std::vector<T>> {
            static constexpr void Call(ObjectContentHasher* recorder, const std::vector<T>& vec) {
                recorder->RecordIterable<std::vector<T>>(vec);
            }
        };

        template <typename IteratorT>
        constexpr void RecordIterable(const IteratorT& iterable) {
            for (auto it = iterable.begin(); it != iterable.end(); ++it) {
                Record(*it);
            }
        }

        size_t mContentHash = 0;
    };

    template <>
    struct ObjectContentHasher::RecordImpl<std::string> {
        static constexpr void Call(ObjectContentHasher* recorder, const std::string& str) {
            recorder->RecordIterable<std::string>(str);
        }
    };

}  // namespace dawn::native

#endif  // DAWNNATIVE_OBJECT_CONTENT_HASHER_H_
