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

#include "dawn/common/Assert.h"
#include "dawn/common/vulkan_platform.h"
#include "dawn/native/CacheKey.h"

#include "vulkan-tools/src/icd/generated/vk_typemap_helper.h"

#include <map>

namespace dawn::native::vulkan {

    namespace detail {

        template <typename... VK_STRUCT_TYPES>
        void ValidatePnextImpl(const VkBaseOutStructure* root) {
            const VkBaseOutStructure* next =
                reinterpret_cast<const VkBaseOutStructure*>(root->pNext);
            while (next != nullptr) {
                // Assert that the type of each pNext struct is exactly one of the specified
                // templates.
                ASSERT(((LvlTypeMap<VK_STRUCT_TYPES>::kSType == next->sType ? 1 : 0) + ... + 0) ==
                       1);
                next = reinterpret_cast<const VkBaseOutStructure*>(next->pNext);
            }
        }

        template <typename VK_STRUCT_TYPE>
        void SerializePnextImpl(CacheKey* key, const VkBaseOutStructure* root) {
            const VkBaseOutStructure* next =
                reinterpret_cast<const VkBaseOutStructure*>(root->pNext);
            const VK_STRUCT_TYPE* found = nullptr;
            while (next != nullptr) {
                if (LvlTypeMap<VK_STRUCT_TYPE>::kSType == next->sType) {
                    if (found == nullptr) {
                        found = reinterpret_cast<const VK_STRUCT_TYPE*>(next);
                    } else {
                        // Fail an assert here since that means that the chain had more than one of
                        // the same typed chained object.
                        ASSERT(false);
                    }
                }
                next = reinterpret_cast<const VkBaseOutStructure*>(next->pNext);
            }
            if (found != nullptr) {
                key->Record(found);
            }
        }

        template <typename VK_STRUCT_TYPE,
                  typename... VK_STRUCT_TYPES,
                  typename = std::enable_if_t<(sizeof...(VK_STRUCT_TYPES) > 0)>>
        void SerializePnextImpl(CacheKey* key, const VkBaseOutStructure* root) {
            SerializePnextImpl<VK_STRUCT_TYPE>(key, root);
            SerializePnextImpl<VK_STRUCT_TYPES...>(key, root);
        }

    }  // namespace detail

    template <typename... VK_STRUCT_TYPES>
    void SerializePnext(CacheKey* key, const VkBaseOutStructure* root) {
        detail::ValidatePnextImpl<VK_STRUCT_TYPES...>(root);
        detail::SerializePnextImpl<VK_STRUCT_TYPES...>(key, root);
    }

    // Empty template specialization so that we can put this in to ensure failures occur if new
    // extensions are added without updating serialization.
    template <>
    void SerializePnext(CacheKey* key, const VkBaseOutStructure* root) {
        detail::ValidatePnextImpl<>(root);
    }

}  // namespace dawn::native::vulkan

#endif  // SRC_DAWN_NATIVE_VULKAN_CACHEKEYVK_H_
