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

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "dawn/native/ChainUtils.h"
#include "dawn/native/dawn_platform.h"

namespace dawn::native {
namespace {

using ::testing::HasSubstr;

// Checks that we cannot find any structs in an empty chain
TEST(ChainUtilsTests, FindEmptyChain) {
    {
        const PrimitiveDepthClipControl* info = nullptr;
        const ChainedStruct* chained = nullptr;
        FindInChain(chained, &info);

        ASSERT_EQ(nullptr, info);
    }

    {
        DawnAdapterPropertiesPowerPreference* info = nullptr;
        ChainedStructOut* chained = nullptr;
        FindInChain(chained, &info);

        ASSERT_EQ(nullptr, info);
    }
}

// Checks that searching a chain for a present struct returns that struct
TEST(ChainUtilsTests, FindPresentInChain) {
    {
        PrimitiveDepthClipControl chain1;
        ShaderModuleSPIRVDescriptor chain2;
        chain1.nextInChain = &chain2;
        const PrimitiveDepthClipControl* info1 = nullptr;
        const ShaderModuleSPIRVDescriptor* info2 = nullptr;
        FindInChain(&chain1, &info1);
        FindInChain(&chain1, &info2);

        ASSERT_NE(nullptr, info1);
        ASSERT_NE(nullptr, info2);
    }

    {
        DawnAdapterPropertiesPowerPreference chain;
        DawnAdapterPropertiesPowerPreference* output = nullptr;
        FindInChain(&chain, &output);

        ASSERT_NE(nullptr, output);
    }
}

// Checks that searching a chain for a struct that doesn't exist returns a nullptr
TEST(ChainUtilsTests, FindMissingInChain) {
    {
        PrimitiveDepthClipControl chain1;
        ShaderModuleSPIRVDescriptor chain2;
        chain1.nextInChain = &chain2;
        const SurfaceDescriptorFromMetalLayer* info = nullptr;
        FindInChain(&chain1, &info);

        ASSERT_EQ(nullptr, info);
    }

    {
        AdapterProperties adapterProperties;
        DawnAdapterPropertiesPowerPreference* output = nullptr;
        FindInChain(adapterProperties.nextInChain, &output);

        ASSERT_EQ(nullptr, output);
    }
}

// Checks that validation rejects chains with duplicate STypes
TEST(ChainUtilsTests, ValidateDuplicateSTypes) {
    {
        PrimitiveDepthClipControl chain1;
        ShaderModuleSPIRVDescriptor chain2;
        PrimitiveDepthClipControl chain3;
        chain1.nextInChain = &chain2;
        chain2.nextInChain = &chain3;

        MaybeError result = ValidateSTypes(&chain1, {});
        ASSERT_TRUE(result.IsError());
        result.AcquireError();
    }

    {
        DawnAdapterPropertiesPowerPreference chain1;
        DawnAdapterPropertiesPowerPreference chain2;
        chain1.nextInChain = &chain2;

        MaybeError result = ValidateSTypes(&chain1, {});
        ASSERT_TRUE(result.IsError());
        result.AcquireError();
    }
}

// Checks that validation rejects chains that contain unspecified STypes
TEST(ChainUtilsTests, ValidateUnspecifiedSTypes) {
    {
        PrimitiveDepthClipControl chain1;
        ShaderModuleSPIRVDescriptor chain2;
        ShaderModuleWGSLDescriptor chain3;
        chain1.nextInChain = &chain2;
        chain2.nextInChain = &chain3;

        MaybeError result = ValidateSTypes(&chain1, {
                                                        {wgpu::SType::PrimitiveDepthClipControl},
                                                        {wgpu::SType::ShaderModuleSPIRVDescriptor},
                                                    });
        ASSERT_TRUE(result.IsError());
        result.AcquireError();
    }

    {
        DawnAdapterPropertiesPowerPreference chain1;
        ChainedStructOut chain2;
        chain2.sType = wgpu::SType::RenderPassDescriptorMaxDrawCount;
        chain1.nextInChain = &chain2;

        MaybeError result =
            ValidateSTypes(&chain1, {{wgpu::SType::DawnAdapterPropertiesPowerPreference}});
        ASSERT_TRUE(result.IsError());
        result.AcquireError();
    }
}

// Checks that validation rejects chains that contain multiple STypes from the same oneof
// constraint.
TEST(ChainUtilsTests, ValidateOneOfFailure) {
    PrimitiveDepthClipControl chain1;
    ShaderModuleSPIRVDescriptor chain2;
    ShaderModuleWGSLDescriptor chain3;
    chain1.nextInChain = &chain2;
    chain2.nextInChain = &chain3;

    MaybeError result = ValidateSTypes(&chain1, {{wgpu::SType::ShaderModuleSPIRVDescriptor,
                                                  wgpu::SType::ShaderModuleWGSLDescriptor}});
    ASSERT_TRUE(result.IsError());
    result.AcquireError();
}

// Checks that validation accepts chains that match the constraints.
TEST(ChainUtilsTests, ValidateSuccess) {
    {
        PrimitiveDepthClipControl chain1;
        ShaderModuleSPIRVDescriptor chain2;
        chain1.nextInChain = &chain2;

        MaybeError result = ValidateSTypes(
            &chain1,
            {
                {wgpu::SType::ShaderModuleSPIRVDescriptor, wgpu::SType::ShaderModuleWGSLDescriptor},
                {wgpu::SType::PrimitiveDepthClipControl},
                {wgpu::SType::SurfaceDescriptorFromMetalLayer},
            });
        ASSERT_TRUE(result.IsSuccess());
    }

    {
        DawnAdapterPropertiesPowerPreference chain1;
        MaybeError result =
            ValidateSTypes(&chain1, {{wgpu::SType::DawnAdapterPropertiesPowerPreference}});
        ASSERT_TRUE(result.IsSuccess());
    }
}

// Checks that validation always passes on empty chains.
TEST(ChainUtilsTests, ValidateEmptyChain) {
    {
        const ChainedStruct* chain = nullptr;
        MaybeError result = ValidateSTypes(chain, {
                                                      {wgpu::SType::ShaderModuleSPIRVDescriptor},
                                                      {wgpu::SType::PrimitiveDepthClipControl},
                                                  });
        ASSERT_TRUE(result.IsSuccess());

        result = ValidateSTypes(chain, {});
        ASSERT_TRUE(result.IsSuccess());
    }

    {
        ChainedStructOut* chain = nullptr;
        MaybeError result =
            ValidateSTypes(chain, {{wgpu::SType::DawnAdapterPropertiesPowerPreference}});
        ASSERT_TRUE(result.IsSuccess());

        result = ValidateSTypes(chain, {});
        ASSERT_TRUE(result.IsSuccess());
    }
}

// Checks that singleton validation always passes on empty chains.
TEST(ChainUtilsTests, ValidateSingleEmptyChain) {
    {
        const ChainedStruct* chain = nullptr;
        MaybeError result = ValidateSingleSType(chain, wgpu::SType::ShaderModuleSPIRVDescriptor);
        ASSERT_TRUE(result.IsSuccess());

        result = ValidateSingleSType(chain, wgpu::SType::ShaderModuleSPIRVDescriptor,
                                     wgpu::SType::PrimitiveDepthClipControl);
        ASSERT_TRUE(result.IsSuccess());
    }

    {
        ChainedStructOut* chain = nullptr;
        MaybeError result =
            ValidateSingleSType(chain, wgpu::SType::DawnAdapterPropertiesPowerPreference);
        ASSERT_TRUE(result.IsSuccess());

        result = ValidateSingleSType(chain, wgpu::SType::DawnAdapterPropertiesPowerPreference,
                                     wgpu::SType::PrimitiveDepthClipControl);
        ASSERT_TRUE(result.IsSuccess());
    }
}

// Checks that singleton validation always fails on chains with multiple children.
TEST(ChainUtilsTests, ValidateSingleMultiChain) {
    {
        PrimitiveDepthClipControl chain1;
        ShaderModuleSPIRVDescriptor chain2;
        chain1.nextInChain = &chain2;

        MaybeError result = ValidateSingleSType(&chain1, wgpu::SType::PrimitiveDepthClipControl);
        ASSERT_TRUE(result.IsError());
        result.AcquireError();

        result = ValidateSingleSType(&chain1, wgpu::SType::PrimitiveDepthClipControl,
                                     wgpu::SType::ShaderModuleSPIRVDescriptor);
        ASSERT_TRUE(result.IsError());
        result.AcquireError();
    }

    {
        DawnAdapterPropertiesPowerPreference chain1;
        DawnAdapterPropertiesPowerPreference chain2;
        chain1.nextInChain = &chain2;

        MaybeError result =
            ValidateSingleSType(&chain1, wgpu::SType::DawnAdapterPropertiesPowerPreference);
        ASSERT_TRUE(result.IsError());
        result.AcquireError();
    }
}

// Checks that singleton validation passes when the one of constraint is met.
TEST(ChainUtilsTests, ValidateSingleSatisfied) {
    {
        ShaderModuleWGSLDescriptor chain1;

        MaybeError result = ValidateSingleSType(&chain1, wgpu::SType::ShaderModuleWGSLDescriptor);
        ASSERT_TRUE(result.IsSuccess());

        result = ValidateSingleSType(&chain1, wgpu::SType::ShaderModuleSPIRVDescriptor,
                                     wgpu::SType::ShaderModuleWGSLDescriptor);
        ASSERT_TRUE(result.IsSuccess());

        result = ValidateSingleSType(&chain1, wgpu::SType::ShaderModuleWGSLDescriptor,
                                     wgpu::SType::ShaderModuleSPIRVDescriptor);
        ASSERT_TRUE(result.IsSuccess());
    }

    {
        DawnAdapterPropertiesPowerPreference chain1;
        MaybeError result =
            ValidateSingleSType(&chain1, wgpu::SType::DawnAdapterPropertiesPowerPreference);
        ASSERT_TRUE(result.IsSuccess());
    }
}

// Checks that singleton validation passes when the oneof constraint is not met.
TEST(ChainUtilsTests, ValidateSingleUnsatisfied) {
    {
        PrimitiveDepthClipControl chain1;

        MaybeError result = ValidateSingleSType(&chain1, wgpu::SType::ShaderModuleWGSLDescriptor);
        ASSERT_TRUE(result.IsError());
        result.AcquireError();

        result = ValidateSingleSType(&chain1, wgpu::SType::ShaderModuleSPIRVDescriptor,
                                     wgpu::SType::ShaderModuleWGSLDescriptor);
        ASSERT_TRUE(result.IsError());
        result.AcquireError();
    }

    {
        ChainedStructOut chain1;
        chain1.sType = wgpu::SType::ShaderModuleWGSLDescriptor;

        MaybeError result =
            ValidateSingleSType(&chain1, wgpu::SType::DawnAdapterPropertiesPowerPreference);
        ASSERT_TRUE(result.IsError());
        result.AcquireError();
    }
}

// Empty chain on roots that have and don't have valid extensions should not fail validation and all
// values should be nullptr.
TEST(ChainUtilsTests, ValidateAndUnpackEmpty) {
    {
        // TextureViewDescriptor (as of when this test was written) does not have any valid chains
        // in the JSON nor via additional extensions.
        TextureViewDescriptor desc;
        auto unpacked = ValidateAndUnpackChain(&desc).AcquireSuccess();
        static_assert(std::tuple_size_v<decltype(unpacked)> == 0);
        std::apply(
            [](const auto*... args) {
                (([&](const auto* arg) { EXPECT_EQ(args, nullptr); }(args)), ...);
            },
            unpacked);
    }
    {
        // InstanceDescriptor has at least 1 valid chain extension.
        InstanceDescriptor desc;
        auto unpacked = ValidateAndUnpackChain(&desc).AcquireSuccess();
        std::apply(
            [](const auto*... args) {
                (([&](const auto* arg) { EXPECT_EQ(args, nullptr); }(args)), ...);
            },
            unpacked);
    }
}

// Invalid chain extensions should cause an error.
TEST(ChainUtilsTests, ValidateAndUnpackUnexpected) {
    {
        // TextureViewDescriptor (as of when this test was written) does not have any valid chains
        // in the JSON nor via additional extensions.
        TextureViewDescriptor desc;
        ChainedStruct chain;
        desc.nextInChain = &chain;
        EXPECT_THAT(ValidateAndUnpackChain(&desc).AcquireError()->GetFormattedMessage(),
                    HasSubstr("Unexpected"));
    }
    {
        // InstanceDescriptor has at least 1 valid chain extension.
        InstanceDescriptor desc;
        ChainedStruct chain;
        desc.nextInChain = &chain;
        EXPECT_THAT(ValidateAndUnpackChain(&desc).AcquireError()->GetFormattedMessage(),
                    HasSubstr("Unexpected"));
    }
}

// Nominal unpacking valid descriptors should return the expected descriptors in the unpacked type.
TEST(ChainUtilsTests, ValidateAndUnpack) {
    // DawnTogglesDescriptor is a valid extension for InstanceDescriptor.
    InstanceDescriptor desc;
    DawnTogglesDescriptor chain;
    desc.nextInChain = &chain;
    auto unpacked = ValidateAndUnpackChain(&desc).AcquireSuccess();
    EXPECT_EQ(std::get<const DawnTogglesDescriptor*>(unpacked), &chain);
}

// Duplicate valid extensions should cause an error.
TEST(ChainUtilsTests, ValidateAndUnpackDuplicate) {
    // DawnTogglesDescriptor is a valid extension for InstanceDescriptor.
    InstanceDescriptor desc;
    DawnTogglesDescriptor chain1;
    DawnTogglesDescriptor chain2;
    desc.nextInChain = &chain1;
    chain1.nextInChain = &chain2;
    EXPECT_THAT(ValidateAndUnpackChain(&desc).AcquireError()->GetFormattedMessage(),
                HasSubstr("Duplicate"));
}

// Additional extensions added via template specialization and not specified in the JSON should work
// properly.
TEST(ChainUtilsTests, ValidateAndUnpackAdditionalExtensions) {
    // DawnInstanceDescriptor is an extension on InstanceDescriptor added in ChainUtilsImpl.h.
    InstanceDescriptor desc;
    DawnInstanceDescriptor chain;
    desc.nextInChain = &chain;
    auto unpacked = ValidateAndUnpackChain(&desc).AcquireSuccess();
    EXPECT_EQ(std::get<const DawnInstanceDescriptor*>(unpacked), &chain);
}

// Duplicate additional extensions added via template specialization should cause an error.
TEST(ChainUtilsTests, ValidateAndUnpackDuplicateAdditionalExtensions) {
    // DawnInstanceDescriptor is an extension on InstanceDescriptor added in ChainUtilsImpl.h.
    InstanceDescriptor desc;
    DawnInstanceDescriptor chain1;
    DawnInstanceDescriptor chain2;
    desc.nextInChain = &chain1;
    chain1.nextInChain = &chain2;
    EXPECT_THAT(ValidateAndUnpackChain(&desc).AcquireError()->GetFormattedMessage(),
                HasSubstr("Duplicate"));
}

}  // anonymous namespace
}  // namespace dawn::native
