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

// 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 = ValidateAndUnpack(&desc).AcquireSuccess();
        static_assert(std::tuple_size_v<decltype(unpacked)::TupleType> == 0);
        EXPECT_TRUE(unpacked.Empty());
    }
    {
        // InstanceDescriptor has at least 1 valid chain extension.
        InstanceDescriptor desc;
        auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
        EXPECT_TRUE(unpacked.Empty());
    }
    {
        // SharedTextureMemoryProperties (as of when this test was written) does not have any valid
        // chains in the JSON nor via additional extensions.
        SharedTextureMemoryProperties properties;
        auto unpacked = ValidateAndUnpack(&properties).AcquireSuccess();
        static_assert(std::tuple_size_v<decltype(unpacked)::TupleType> == 0);
        EXPECT_TRUE(unpacked.Empty());
    }
    {
        // SharedFenceExportInfo has at least 1 valid chain extension.
        SharedFenceExportInfo properties;
        auto unpacked = ValidateAndUnpack(&properties).AcquireSuccess();
        EXPECT_TRUE(unpacked.Empty());
    }
}

// Invalid chain extensions 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(ValidateAndUnpack(&desc).AcquireError()->GetFormattedMessage(),
                    HasSubstr("Unexpected"));
    }
    {
        // InstanceDescriptor has at least 1 valid chain extension.
        InstanceDescriptor desc;
        ChainedStruct chain;
        desc.nextInChain = &chain;
        EXPECT_THAT(ValidateAndUnpack(&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 = ValidateAndUnpack(&desc).AcquireSuccess();
    auto ext = unpacked.Get<DawnTogglesDescriptor>();
    EXPECT_EQ(ext, &chain);

    // For ChainedStructs, the resulting pointer from Get should be a const type.
    static_assert(std::is_const_v<std::remove_reference_t<decltype(*ext)>>);
}

// Nominal unpacking valid descriptors should return the expected descriptors in the unpacked type.
TEST(ChainUtilsTests, ValidateAndUnpackOut) {
    // DawnAdapterPropertiesPowerPreference is a valid extension for AdapterProperties.
    AdapterProperties properties;
    DawnAdapterPropertiesPowerPreference chain;
    properties.nextInChain = &chain;
    auto unpacked = ValidateAndUnpack(&properties).AcquireSuccess();
    auto ext = unpacked.Get<DawnAdapterPropertiesPowerPreference>();
    EXPECT_EQ(ext, &chain);

    // For ChainedStructOuts, the resulting pointer from Get should not be a const type.
    static_assert(!std::is_const_v<std::remove_reference_t<decltype(*ext)>>);
}

// Duplicate valid extensions 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(ValidateAndUnpack(&desc).AcquireError()->GetFormattedMessage(),
                HasSubstr("Duplicate"));
}

// Duplicate valid extensions cause an error.
TEST(ChainUtilsTests, ValidateAndUnpackOutDuplicate) {
    // DawnAdapterPropertiesPowerPreference is a valid extension for AdapterProperties.
    AdapterProperties properties;
    DawnAdapterPropertiesPowerPreference chain1;
    DawnAdapterPropertiesPowerPreference chain2;
    properties.nextInChain = &chain1;
    chain1.nextInChain = &chain2;
    EXPECT_THAT(ValidateAndUnpack(&properties).AcquireError()->GetFormattedMessage(),
                HasSubstr("Duplicate"));
}

// Additional extensions added via template specialization and not specified in the JSON unpack
// properly.
TEST(ChainUtilsTests, ValidateAndUnpackAdditionalExtensions) {
    // DawnInstanceDescriptor is an extension on InstanceDescriptor added in ChainUtilsImpl.inl.
    InstanceDescriptor desc;
    DawnInstanceDescriptor chain;
    desc.nextInChain = &chain;
    auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
    EXPECT_EQ(unpacked.Get<DawnInstanceDescriptor>(), &chain);
}

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

using B1 = Branch<ShaderModuleWGSLDescriptor>;
using B2 = Branch<ShaderModuleSPIRVDescriptor>;
using B2Ext = Branch<ShaderModuleSPIRVDescriptor, DawnShaderModuleSPIRVOptionsDescriptor>;

// Validates exacly 1 branch and ensures that there are no other extensions.
TEST(ChainUtilsTests, ValidateBranchesOneValidBranch) {
    ShaderModuleDescriptor desc;
    // Either allowed branches should validate successfully and return the expected enum.
    {
        ShaderModuleWGSLDescriptor chain;
        desc.nextInChain = &chain;
        auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
        EXPECT_EQ((unpacked.ValidateBranches<B1, B2>().AcquireSuccess()),
                  wgpu::SType::ShaderModuleWGSLDescriptor);
    }
    {
        ShaderModuleSPIRVDescriptor chain;
        desc.nextInChain = &chain;
        auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
        EXPECT_EQ((unpacked.ValidateBranches<B1, B2>().AcquireSuccess()),
                  wgpu::SType::ShaderModuleSPIRVDescriptor);

        // Extensions are optional so validation should still pass when the extension is not
        // provided.
        EXPECT_EQ((unpacked.ValidateBranches<B1, B2Ext>().AcquireSuccess()),
                  wgpu::SType::ShaderModuleSPIRVDescriptor);
    }
}

// An allowed chain that is not one of the branches causes an error.
TEST(ChainUtilsTests, ValidateBranchesInvalidBranch) {
    ShaderModuleDescriptor desc;
    DawnShaderModuleSPIRVOptionsDescriptor chain;
    desc.nextInChain = &chain;
    auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
    EXPECT_NE((unpacked.ValidateBranches<B1, B2>().AcquireError()), nullptr);
    EXPECT_NE((unpacked.ValidateBranches<B1, B2Ext>().AcquireError()), nullptr);
}

// Additional chains should cause an error when branches don't allow extensions.
TEST(ChainUtilsTests, ValidateBranchesInvalidExtension) {
    ShaderModuleDescriptor desc;
    {
        ShaderModuleWGSLDescriptor chain1;
        DawnShaderModuleSPIRVOptionsDescriptor chain2;
        desc.nextInChain = &chain1;
        chain1.nextInChain = &chain2;
        auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
        EXPECT_NE((unpacked.ValidateBranches<B1, B2>().AcquireError()), nullptr);
        EXPECT_NE((unpacked.ValidateBranches<B1, B2Ext>().AcquireError()), nullptr);
    }
    {
        ShaderModuleSPIRVDescriptor chain1;
        DawnShaderModuleSPIRVOptionsDescriptor chain2;
        desc.nextInChain = &chain1;
        chain1.nextInChain = &chain2;
        auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
        EXPECT_NE((unpacked.ValidateBranches<B1, B2>().AcquireError()), nullptr);
    }
}

// Branches that allow extensions pass successfully.
TEST(ChainUtilsTests, ValidateBranchesAllowedExtensions) {
    ShaderModuleDescriptor desc;
    ShaderModuleSPIRVDescriptor chain1;
    DawnShaderModuleSPIRVOptionsDescriptor chain2;
    desc.nextInChain = &chain1;
    chain1.nextInChain = &chain2;
    auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
    EXPECT_EQ((unpacked.ValidateBranches<B1, B2Ext>().AcquireSuccess()),
              wgpu::SType::ShaderModuleSPIRVDescriptor);
}

// Unrealistic branching for ChainedStructOut testing. Note that this setup does not make sense.
using BOut1 = Branch<SharedFenceVkSemaphoreOpaqueFDExportInfo>;
using BOut2 = Branch<SharedFenceVkSemaphoreSyncFDExportInfo>;
using BOut2Ext =
    Branch<SharedFenceVkSemaphoreSyncFDExportInfo, SharedFenceVkSemaphoreZirconHandleExportInfo>;

// Validates exacly 1 branch and ensures that there are no other extensions.
TEST(ChainUtilsTests, ValidateBranchesOneValidBranchOut) {
    SharedFenceExportInfo info;
    // Either allowed branches should validate successfully and return the expected enum.
    {
        SharedFenceVkSemaphoreOpaqueFDExportInfo chain;
        info.nextInChain = &chain;
        auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
        EXPECT_EQ((unpacked.ValidateBranches<BOut1, BOut2>().AcquireSuccess()),
                  wgpu::SType::SharedFenceVkSemaphoreOpaqueFDExportInfo);
    }
    {
        SharedFenceVkSemaphoreSyncFDExportInfo chain;
        info.nextInChain = &chain;
        auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
        EXPECT_EQ((unpacked.ValidateBranches<BOut1, BOut2>().AcquireSuccess()),
                  wgpu::SType::SharedFenceVkSemaphoreSyncFDExportInfo);

        // Extensions are optional so validation should still pass when the extension is not
        // provided.
        EXPECT_EQ((unpacked.ValidateBranches<BOut1, BOut2Ext>().AcquireSuccess()),
                  wgpu::SType::SharedFenceVkSemaphoreSyncFDExportInfo);
    }
}

// An allowed chain that is not one of the branches causes an error.
TEST(ChainUtilsTests, ValidateBranchesInvalidBranchOut) {
    SharedFenceExportInfo info;
    SharedFenceDXGISharedHandleExportInfo chain;
    info.nextInChain = &chain;
    auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
    EXPECT_NE((unpacked.ValidateBranches<BOut1, BOut2>().AcquireError()), nullptr);
    EXPECT_NE((unpacked.ValidateBranches<BOut1, BOut2Ext>().AcquireError()), nullptr);
}

// Additional chains should cause an error when branches don't allow extensions.
TEST(ChainUtilsTests, ValidateBranchesInvalidExtensionOut) {
    SharedFenceExportInfo info;
    {
        SharedFenceVkSemaphoreOpaqueFDExportInfo chain1;
        SharedFenceVkSemaphoreZirconHandleExportInfo chain2;
        info.nextInChain = &chain1;
        chain1.nextInChain = &chain2;
        auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
        EXPECT_NE((unpacked.ValidateBranches<BOut1, BOut2>().AcquireError()), nullptr);
        EXPECT_NE((unpacked.ValidateBranches<BOut1, BOut2Ext>().AcquireError()), nullptr);
    }
    {
        SharedFenceVkSemaphoreSyncFDExportInfo chain1;
        SharedFenceVkSemaphoreZirconHandleExportInfo chain2;
        info.nextInChain = &chain1;
        chain1.nextInChain = &chain2;
        auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
        EXPECT_NE((unpacked.ValidateBranches<BOut1, BOut2>().AcquireError()), nullptr);
    }
}

// Branches that allow extensions pass successfully.
TEST(ChainUtilsTests, ValidateBranchesAllowedExtensionsOut) {
    SharedFenceExportInfo info;
    SharedFenceVkSemaphoreSyncFDExportInfo chain1;
    SharedFenceVkSemaphoreZirconHandleExportInfo chain2;
    info.nextInChain = &chain1;
    chain1.nextInChain = &chain2;
    auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
    EXPECT_EQ((unpacked.ValidateBranches<BOut1, BOut2Ext>().AcquireSuccess()),
              wgpu::SType::SharedFenceVkSemaphoreSyncFDExportInfo);
}

// Valid subsets should pass successfully, while invalid ones should error.
TEST(ChainUtilsTests, ValidateSubset) {
    DeviceDescriptor desc;
    DawnTogglesDescriptor chain1;
    DawnCacheDeviceDescriptor chain2;

    // With none set, subset for anything should work.
    {
        auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
        EXPECT_TRUE(unpacked.ValidateSubset<>().IsSuccess());
        EXPECT_TRUE(unpacked.ValidateSubset<DawnTogglesDescriptor>().IsSuccess());
        EXPECT_TRUE(unpacked.ValidateSubset<DawnCacheDeviceDescriptor>().IsSuccess());
        EXPECT_TRUE((unpacked.ValidateSubset<DawnTogglesDescriptor, DawnCacheDeviceDescriptor>()
                         .IsSuccess()));
    }
    // With one set, subset with that allow that one should pass. Otherwise it should fail.
    {
        desc.nextInChain = &chain1;
        auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
        EXPECT_NE(unpacked.ValidateSubset<>().AcquireError(), nullptr);
        EXPECT_TRUE(unpacked.ValidateSubset<DawnTogglesDescriptor>().IsSuccess());
        EXPECT_NE(unpacked.ValidateSubset<DawnCacheDeviceDescriptor>().AcquireError(), nullptr);
        EXPECT_TRUE((unpacked.ValidateSubset<DawnTogglesDescriptor, DawnCacheDeviceDescriptor>()
                         .IsSuccess()));
    }
    // With both set, single subsets should all fail.
    {
        chain1.nextInChain = &chain2;
        auto unpacked = ValidateAndUnpack(&desc).AcquireSuccess();
        EXPECT_NE(unpacked.ValidateSubset<>().AcquireError(), nullptr);
        EXPECT_NE(unpacked.ValidateSubset<DawnTogglesDescriptor>().AcquireError(), nullptr);
        EXPECT_NE(unpacked.ValidateSubset<DawnCacheDeviceDescriptor>().AcquireError(), nullptr);
        EXPECT_TRUE((unpacked.ValidateSubset<DawnTogglesDescriptor, DawnCacheDeviceDescriptor>()
                         .IsSuccess()));
    }
}

// Valid subsets should pass successfully, while invalid ones should error.
TEST(ChainUtilsTests, ValidateSubsetOut) {
    SharedFenceExportInfo info;
    SharedFenceVkSemaphoreOpaqueFDExportInfo chain1;
    SharedFenceVkSemaphoreZirconHandleExportInfo chain2;

    // With none set, subset for anything should work.
    {
        auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
        EXPECT_TRUE(unpacked.ValidateSubset<>().IsSuccess());
        EXPECT_TRUE(
            unpacked.ValidateSubset<SharedFenceVkSemaphoreOpaqueFDExportInfo>().IsSuccess());
        EXPECT_TRUE(
            unpacked.ValidateSubset<SharedFenceVkSemaphoreZirconHandleExportInfo>().IsSuccess());
        EXPECT_TRUE((unpacked
                         .ValidateSubset<SharedFenceVkSemaphoreOpaqueFDExportInfo,
                                         SharedFenceVkSemaphoreZirconHandleExportInfo>()
                         .IsSuccess()));
    }
    // With one set, subset with that allow that one should pass. Otherwise it should fail.
    {
        info.nextInChain = &chain1;
        auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
        EXPECT_NE(unpacked.ValidateSubset<>().AcquireError(), nullptr);
        EXPECT_TRUE(
            unpacked.ValidateSubset<SharedFenceVkSemaphoreOpaqueFDExportInfo>().IsSuccess());
        EXPECT_NE(
            unpacked.ValidateSubset<SharedFenceVkSemaphoreZirconHandleExportInfo>().AcquireError(),
            nullptr);
        EXPECT_TRUE((unpacked
                         .ValidateSubset<SharedFenceVkSemaphoreOpaqueFDExportInfo,
                                         SharedFenceVkSemaphoreZirconHandleExportInfo>()
                         .IsSuccess()));
    }
    // With both set, single subsets should all fail.
    {
        chain1.nextInChain = &chain2;
        auto unpacked = ValidateAndUnpack(&info).AcquireSuccess();
        EXPECT_NE(unpacked.ValidateSubset<>().AcquireError(), nullptr);
        EXPECT_NE(
            unpacked.ValidateSubset<SharedFenceVkSemaphoreOpaqueFDExportInfo>().AcquireError(),
            nullptr);
        EXPECT_NE(
            unpacked.ValidateSubset<SharedFenceVkSemaphoreZirconHandleExportInfo>().AcquireError(),
            nullptr);
        EXPECT_TRUE((unpacked
                         .ValidateSubset<SharedFenceVkSemaphoreOpaqueFDExportInfo,
                                         SharedFenceVkSemaphoreZirconHandleExportInfo>()
                         .IsSuccess()));
    }
}

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