// Copyright 2023 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 <algorithm>
#include <vector>

#include "src/dawn/tests/unittests/validation/ValidationTest.h"
#include "src/dawn/utils/WGPUHelpers.h"
#include "src/dawn/utils/WireHelper.h"
#include "src/utils/compiler.h"

namespace dawn {
namespace {

class WGSLFeatureValidationTest : public ValidationTest {
  protected:
    struct InstanceSpec {
        bool useTestingFeatures = true;
        bool allowUnsafeAPIs = false;
        bool exposeExperimental = false;
        std::vector<const char*> blocklist = {};
    };

    // Override the default SetUp to do nothing since the tests will call SetUp(InstanceSpec)
    // explicitly each time.
    void SetUp() override {}
    void SetUp(InstanceSpec spec) {
        // The blocklist that will be shared between both the native and wire descriptors.
        wgpu::DawnWGSLBlocklist blocklist;
        blocklist.blocklistedFeatureCount = spec.blocklist.size();
        blocklist.blocklistedFeatures = spec.blocklist.data();

        // Build the native instance descriptor.
        std::vector<const char*> enabledToggles;
        if (spec.useTestingFeatures) {
            enabledToggles.push_back("expose_wgsl_testing_features");
        }
        if (spec.allowUnsafeAPIs) {
            enabledToggles.push_back("allow_unsafe_apis");
        }
        if (spec.exposeExperimental) {
            enabledToggles.push_back("expose_wgsl_experimental_features");
        }

        wgpu::DawnTogglesDescriptor togglesDesc;
        togglesDesc.nextInChain = &blocklist;
        togglesDesc.enabledToggleCount = enabledToggles.size();
        togglesDesc.enabledToggles = enabledToggles.data();

        wgpu::InstanceDescriptor nativeDesc;
        nativeDesc.nextInChain = &togglesDesc;

        // Build the wire instance descriptor.
        wgpu::DawnWireWGSLControl wgslControl;
        wgslControl.nextInChain = &blocklist;
        wgslControl.enableExperimental = spec.allowUnsafeAPIs || spec.exposeExperimental;
        wgslControl.enableUnsafe = spec.allowUnsafeAPIs;
        wgslControl.enableTesting = spec.useTestingFeatures;

        wgpu::InstanceDescriptor wireDesc;
        wireDesc.nextInChain = &wgslControl;

        ValidationTest::SetUp(&nativeDesc, &wireDesc);
    }
};

wgpu::WGSLLanguageFeatureName kNonExistentFeature = {};

// Check HasFeature for an Instance that doesn't have unsafe APIs.
TEST_F(WGSLFeatureValidationTest, HasFeatureDefaultInstance) {
    SetUp({});

    // Shipped features are present.
    ASSERT_TRUE(
        instance.HasWGSLLanguageFeature(wgpu::WGSLLanguageFeatureName::ChromiumTestingShipped));
    ASSERT_TRUE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingShippedWithKillswitch));

    // Experimental and unimplemented features are not present.
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingExperimental));
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnsafeExperimental));
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnimplemented));

    // Non-existent features are not present.
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(kNonExistentFeature));
}

// Check HasFeature for an Instance that has unsafe APIs.
TEST_F(WGSLFeatureValidationTest, HasFeatureExposeExperimental) {
    SetUp({.exposeExperimental = true});

    // Shipped and experimental features are present.
    ASSERT_TRUE(
        instance.HasWGSLLanguageFeature(wgpu::WGSLLanguageFeatureName::ChromiumTestingShipped));
    ASSERT_TRUE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingShippedWithKillswitch));
    ASSERT_TRUE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingExperimental));

    // Unsafe and unimplemented features are not present.
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnsafeExperimental));
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnimplemented));

    // Non-existent features are not present.
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(kNonExistentFeature));
}

// Check HasFeature for an Instance that has unsafe APIs.
TEST_F(WGSLFeatureValidationTest, HasFeatureAllowUnsafeInstance) {
    SetUp({.allowUnsafeAPIs = true});

    // Shipped and experimental features are present.
    ASSERT_TRUE(
        instance.HasWGSLLanguageFeature(wgpu::WGSLLanguageFeatureName::ChromiumTestingShipped));
    ASSERT_TRUE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingShippedWithKillswitch));
    ASSERT_TRUE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingExperimental));
    ASSERT_TRUE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnsafeExperimental));

    // Unimplemented features are not present.
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnimplemented));

    // Non-existent features are not present.
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(kNonExistentFeature));
}

// Check HasFeature for an Instance that doesn't have the expose_wgsl_testing_features toggle.
TEST_F(WGSLFeatureValidationTest, HasFeatureWithoutExposeWGSLTestingFeatures) {
    SetUp({.useTestingFeatures = false});

    // None of the testing features are present.
    ASSERT_FALSE(
        instance.HasWGSLLanguageFeature(wgpu::WGSLLanguageFeatureName::ChromiumTestingShipped));
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingShippedWithKillswitch));
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingExperimental));
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnsafeExperimental));
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnimplemented));
}

// Tests for the behavior of getting WGSL language features.
TEST_F(WGSLFeatureValidationTest, GetFeatures) {
    SetUp({});

    wgpu::SupportedWGSLLanguageFeatures supportedFeatures = {};
    instance.GetWGSLLanguageFeatures(&supportedFeatures);
    ASSERT_NE(0u, supportedFeatures.featureCount);
    const wgpu::WGSLLanguageFeatureName* features = supportedFeatures.features;

    // Exactly featureCount features should be written, and all return true in HasWGSLFeature.
    for (size_t i = 0; i < supportedFeatures.featureCount; i++) {
        DAWN_UNSAFE_TODO(ASSERT_TRUE(instance.HasWGSLLanguageFeature(features[i])));
    }

    // Test the presence / absence of some known testing features.
    const wgpu::WGSLLanguageFeatureName* begin = features;
    const wgpu::WGSLLanguageFeatureName* end =
        DAWN_UNSAFE_TODO(features + supportedFeatures.featureCount);
    ASSERT_NE(std::find(begin, end, wgpu::WGSLLanguageFeatureName::ChromiumTestingShipped), end);
    ASSERT_NE(
        std::find(begin, end, wgpu::WGSLLanguageFeatureName::ChromiumTestingShippedWithKillswitch),
        end);

    ASSERT_EQ(std::find(begin, end, wgpu::WGSLLanguageFeatureName::ChromiumTestingUnimplemented),
              end);
    ASSERT_EQ(
        std::find(begin, end, wgpu::WGSLLanguageFeatureName::ChromiumTestingUnsafeExperimental),
        end);
    ASSERT_EQ(std::find(begin, end, wgpu::WGSLLanguageFeatureName::ChromiumTestingExperimental),
              end);
}

// Check that the enabled / disabled features are used to validate the WGSL shaders.
TEST_F(WGSLFeatureValidationTest, UsingFeatureInShaderModule) {
    SetUp({});

    utils::CreateShaderModule(device, R"(
        requires chromium_testing_shipped;
    )");
    utils::CreateShaderModule(device, R"(
        requires chromium_testing_shipped_with_killswitch;
    )");

    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        requires chromium_testing_unimplemented;
    )"));
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        requires chromium_testing_unsafe_experimental;
    )"));
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        requires chromium_testing_experimental;
    )"));
}

// Test using DawnWGSLBlocklist to block features with a killswitch by name.
TEST_F(WGSLFeatureValidationTest, BlockListOfKillswitchedFeatures) {
    SetUp({.allowUnsafeAPIs = true, .blocklist = {"chromium_testing_shipped_with_killswitch"}});

    // The blocklisted feature is not present.
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingShippedWithKillswitch));

    // The others are.
    ASSERT_TRUE(
        instance.HasWGSLLanguageFeature(wgpu::WGSLLanguageFeatureName::ChromiumTestingShipped));
    ASSERT_TRUE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingExperimental));
    ASSERT_TRUE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnsafeExperimental));

    // Using the blocklisted extension fails.
    ASSERT_DEVICE_ERROR(utils::CreateShaderModule(device, R"(
        requires chromium_testing_shipped_with_killswitch;
    )"));
}

// Test that DawnWGSLBlocklist can block experimental features (even without a killswitch).
TEST_F(WGSLFeatureValidationTest, BlockListOfExperimentalFeatures) {
    SetUp({.allowUnsafeAPIs = true,
           .blocklist = {"chromium_testing_experimental", "chromium_testing_unsafe_experimental"}});

    // The blocklisted features are not present.
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingExperimental));
    ASSERT_FALSE(instance.HasWGSLLanguageFeature(
        wgpu::WGSLLanguageFeatureName::ChromiumTestingUnsafeExperimental));
}

// Test that DawnWGSLBlocklist does not remove features that are fully shipped.
TEST_F(WGSLFeatureValidationTest, BlockListOfShippedFeature) {
    SetUp({.allowUnsafeAPIs = true, .blocklist = {"chromium_testing_shipped"}});

    // The shipped feature is still present.
    ASSERT_TRUE(
        instance.HasWGSLLanguageFeature(wgpu::WGSLLanguageFeatureName::ChromiumTestingShipped));
}

// Test that DawnWGSLBlocklist can contain garbage names without causing problems.
TEST_F(WGSLFeatureValidationTest, BlockListGarbageName) {
    SetUp({.blocklist = {"LE_GARBAGE"}});
    ASSERT_NE(instance, nullptr);
}

}  // anonymous namespace
}  // namespace dawn
