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

#include <cstring>
#include <map>

#include "dawn/common/Assert.h"
#include "dawn/common/vulkan_platform.h"
#include "dawn/native/stream/Stream.h"
#include "dawn/native/vulkan/RenderPassCache.h"

#include <vulkan/utility/vk_struct_helper.hpp>  // NOLINT(build/include_order)

namespace dawn::native {

namespace {

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.
        DAWN_ASSERT(((vku::GetSType<VK_STRUCT_TYPES>() == next->sType ? 1 : 0) + ... + 0) == 1);
        next = reinterpret_cast<const VkBaseOutStructure*>(next->pNext);
    }
}

template <typename VK_STRUCT_TYPE>
void SerializePnextImpl(stream::Sink* sink, const VkBaseOutStructure* root) {
    const VkBaseOutStructure* next = reinterpret_cast<const VkBaseOutStructure*>(root->pNext);
    const VK_STRUCT_TYPE* found = nullptr;
    while (next != nullptr) {
        if (vku::GetSType<VK_STRUCT_TYPE>() == 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.
                DAWN_ASSERT(false);
            }
        }
        next = reinterpret_cast<const VkBaseOutStructure*>(next->pNext);
    }
    if (found != nullptr) {
        StreamIn(sink, found);
    }
}

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

template <typename VK_STRUCT_TYPE>
const VkBaseOutStructure* ToVkBaseOutStructure(const VK_STRUCT_TYPE* t) {
    // Checks to ensure proper type safety.
    static_assert(offsetof(VK_STRUCT_TYPE, sType) == offsetof(VkBaseOutStructure, sType) &&
                      offsetof(VK_STRUCT_TYPE, pNext) == offsetof(VkBaseOutStructure, pNext),
                  "Argument type is not a proper Vulkan structure type");
    return reinterpret_cast<const VkBaseOutStructure*>(t);
}

}  // namespace detail

template <typename... VK_STRUCT_TYPES,
          typename VK_STRUCT_TYPE,
          typename = std::enable_if_t<(sizeof...(VK_STRUCT_TYPES) > 0)>>
void SerializePnext(stream::Sink* sink, const VK_STRUCT_TYPE* t) {
    const VkBaseOutStructure* root = detail::ToVkBaseOutStructure(t);
    detail::ValidatePnextImpl<VK_STRUCT_TYPES...>(root);
    detail::SerializePnextImpl<VK_STRUCT_TYPES...>(sink, root);
}

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

}  // namespace

template <>
void stream::Stream<VkDescriptorSetLayoutBinding>::Write(stream::Sink* sink,
                                                         const VkDescriptorSetLayoutBinding& t) {
    StreamIn(sink, t.binding, t.descriptorType, t.descriptorCount, t.stageFlags);
}

template <>
void stream::Stream<VkDescriptorSetLayoutCreateInfo>::Write(
    stream::Sink* sink,
    const VkDescriptorSetLayoutCreateInfo& t) {
    StreamIn(sink, t.flags, Iterable(t.pBindings, t.bindingCount));
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkPushConstantRange>::Write(stream::Sink* sink, const VkPushConstantRange& t) {
    StreamIn(sink, t.stageFlags, t.offset, t.size);
}

template <>
void stream::Stream<VkPipelineLayoutCreateInfo>::Write(stream::Sink* sink,
                                                       const VkPipelineLayoutCreateInfo& t) {
    // The set layouts are not serialized here because they are pointers to backend objects.
    // They need to be cross-referenced with the frontend objects and serialized from there.
    StreamIn(sink, t.flags, Iterable(t.pPushConstantRanges, t.pushConstantRangeCount));
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>::Write(
    stream::Sink* sink,
    const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT& t) {
    StreamIn(sink, t.requiredSubgroupSize);
}

template <>
void stream::Stream<VkPipelineRasterizationDepthClipStateCreateInfoEXT>::Write(
    stream::Sink* sink,
    const VkPipelineRasterizationDepthClipStateCreateInfoEXT& t) {
    StreamIn(sink, t.depthClipEnable, t.flags);
}

template <>
void stream::Stream<VkSpecializationMapEntry>::Write(stream::Sink* sink,
                                                     const VkSpecializationMapEntry& t) {
    StreamIn(sink, t.constantID, t.offset, t.size);
}

template <>
void stream::Stream<VkSpecializationInfo>::Write(stream::Sink* sink,
                                                 const VkSpecializationInfo& t) {
    StreamIn(sink, Iterable(t.pMapEntries, t.mapEntryCount),
             Iterable(static_cast<const uint8_t*>(t.pData), t.dataSize));
}

template <>
void stream::Stream<VkPipelineShaderStageCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineShaderStageCreateInfo& t) {
    // The shader module is not serialized here because it is a pointer to a backend object.
    StreamIn(sink, t.flags, t.stage, Iterable(t.pName, strlen(t.pName)), t.pSpecializationInfo);
    SerializePnext<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>(sink, &t);
}

template <>
void stream::Stream<VkComputePipelineCreateInfo>::Write(stream::Sink* sink,
                                                        const VkComputePipelineCreateInfo& t) {
    // The pipeline layout is not serialized here because it is a pointer to a backend object.
    // It needs to be cross-referenced with the frontend objects and serialized from there. The
    // base pipeline information is also currently not serialized since we do not use them in our
    // backend implementation. If we decide to use them later on, they also need to be
    // cross-referenced from the frontend.
    StreamIn(sink, t.flags, t.stage);
}

template <>
void stream::Stream<VkVertexInputBindingDescription>::Write(
    stream::Sink* sink,
    const VkVertexInputBindingDescription& t) {
    StreamIn(sink, t.binding, t.stride, t.inputRate);
}

template <>
void stream::Stream<VkVertexInputAttributeDescription>::Write(
    stream::Sink* sink,
    const VkVertexInputAttributeDescription& t) {
    StreamIn(sink, t.location, t.binding, t.format, t.offset);
}

template <>
void stream::Stream<VkPipelineVertexInputStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineVertexInputStateCreateInfo& t) {
    StreamIn(sink, t.flags, Iterable(t.pVertexBindingDescriptions, t.vertexBindingDescriptionCount),
             Iterable(t.pVertexAttributeDescriptions, t.vertexAttributeDescriptionCount));
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkPipelineInputAssemblyStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineInputAssemblyStateCreateInfo& t) {
    StreamIn(sink, t.flags, t.topology, t.primitiveRestartEnable);
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkPipelineTessellationStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineTessellationStateCreateInfo& t) {
    StreamIn(sink, t.flags, t.patchControlPoints);
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkViewport>::Write(stream::Sink* sink, const VkViewport& t) {
    StreamIn(sink, t.x, t.y, t.width, t.height, t.minDepth, t.maxDepth);
}

template <>
void stream::Stream<VkOffset2D>::Write(stream::Sink* sink, const VkOffset2D& t) {
    StreamIn(sink, t.x, t.y);
}

template <>
void stream::Stream<VkExtent2D>::Write(stream::Sink* sink, const VkExtent2D& t) {
    StreamIn(sink, t.width, t.height);
}

template <>
void stream::Stream<VkRect2D>::Write(stream::Sink* sink, const VkRect2D& t) {
    StreamIn(sink, t.offset, t.extent);
}

template <>
void stream::Stream<VkPipelineViewportStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineViewportStateCreateInfo& t) {
    StreamIn(sink, t.flags, Iterable(t.pViewports, t.viewportCount),
             Iterable(t.pScissors, t.scissorCount));
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkPipelineRasterizationStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineRasterizationStateCreateInfo& t) {
    StreamIn(sink, t.flags, t.depthClampEnable, t.rasterizerDiscardEnable, t.polygonMode,
             t.cullMode, t.frontFace, t.depthBiasEnable, t.depthBiasConstantFactor,
             t.depthBiasClamp, t.depthBiasSlopeFactor, t.lineWidth);
    SerializePnext<VkPipelineRasterizationDepthClipStateCreateInfoEXT>(sink, &t);
}

template <>
void stream::Stream<VkPipelineMultisampleStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineMultisampleStateCreateInfo& t) {
    StreamIn(sink, t.flags, t.rasterizationSamples, t.sampleShadingEnable, t.minSampleShading,
             t.pSampleMask, t.alphaToCoverageEnable, t.alphaToOneEnable);
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkStencilOpState>::Write(stream::Sink* sink, const VkStencilOpState& t) {
    StreamIn(sink, t.failOp, t.passOp, t.depthFailOp, t.compareOp, t.compareMask, t.writeMask,
             t.reference);
}

template <>
void stream::Stream<VkPipelineDepthStencilStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineDepthStencilStateCreateInfo& t) {
    StreamIn(sink, t.flags, t.depthTestEnable, t.depthWriteEnable, t.depthCompareOp,
             t.depthBoundsTestEnable, t.stencilTestEnable, t.front, t.back, t.minDepthBounds,
             t.maxDepthBounds);
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkPipelineColorBlendAttachmentState>::Write(
    stream::Sink* sink,
    const VkPipelineColorBlendAttachmentState& t) {
    StreamIn(sink, t.blendEnable, t.srcColorBlendFactor, t.dstColorBlendFactor, t.colorBlendOp,
             t.srcAlphaBlendFactor, t.dstAlphaBlendFactor, t.alphaBlendOp, t.colorWriteMask);
}

template <>
void stream::Stream<VkPipelineColorBlendStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineColorBlendStateCreateInfo& t) {
    StreamIn(sink, t.flags, t.logicOpEnable, t.logicOp, Iterable(t.pAttachments, t.attachmentCount),
             t.blendConstants);
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<VkPipelineDynamicStateCreateInfo>::Write(
    stream::Sink* sink,
    const VkPipelineDynamicStateCreateInfo& t) {
    StreamIn(sink, t.flags, Iterable(t.pDynamicStates, t.dynamicStateCount));
    SerializePnext(sink, &t);
}

template <>
void stream::Stream<vulkan::RenderPassCacheQuery>::Write(stream::Sink* sink,
                                                         const vulkan::RenderPassCacheQuery& t) {
    StreamIn(sink, t.colorMask.to_ulong(), t.resolveTargetMask.to_ulong(), t.sampleCount);

    // Manually iterate the color attachment indices and their corresponding format/load/store
    // ops because the data is sparse and may be uninitialized. Since we serialize the colorMask
    // member above, serializing sparse data should be fine here.
    for (auto i : IterateBitSet(t.colorMask)) {
        StreamIn(sink, t.colorFormats[i], t.colorLoadOp[i], t.colorStoreOp[i]);
    }

    // Serialize the depth-stencil toggle bit, and the parameters if applicable.
    StreamIn(sink, t.hasDepthStencil);
    if (t.hasDepthStencil) {
        StreamIn(sink, t.depthStencilFormat, t.depthLoadOp, t.depthStoreOp, t.depthReadOnly,
                 t.stencilLoadOp, t.stencilStoreOp, t.stencilReadOnly);
    }
}

template <>
void stream::Stream<VkGraphicsPipelineCreateInfo>::Write(stream::Sink* sink,
                                                         const VkGraphicsPipelineCreateInfo& t) {
    // The pipeline layout and render pass are not serialized here because they are pointers to
    // backend objects. They need to be cross-referenced with the frontend objects and
    // serialized from there. The base pipeline information is also currently not serialized since
    // we do not use them in our backend implementation. If we decide to use them later on, they
    // also need to be cross-referenced from the frontend.
    StreamIn(sink, t.flags, Iterable(t.pStages, t.stageCount), t.pVertexInputState,
             t.pInputAssemblyState, t.pTessellationState, t.pViewportState, t.pRasterizationState,
             t.pMultisampleState, t.pDepthStencilState, t.pColorBlendState, t.pDynamicState,
             t.subpass);
    SerializePnext(sink, &t);
}

}  // namespace dawn::native
