// Copyright 2025 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 <memory>
#include <string_view>

#include "src/dawn/tests/DawnTest.h"
#include "src/dawn/tests/mocks/platform/CachingInterfaceMock.h"
#include "src/dawn/utils/ComboRenderPipelineDescriptor.h"
#include "src/dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

using ::testing::NiceMock;

static constexpr std::string_view kComputeShaderDefault = R"(
        @compute @workgroup_size(1) fn main() {}
    )";

static constexpr std::string_view kComputeShaderMultipleEntryPoints = R"(
        @compute @workgroup_size(16) fn main() {}
        @compute @workgroup_size(64) fn main2() {}
    )";

class ShaderModuleCachingTests : public DawnTest {
  protected:
    std::unique_ptr<platform::Platform> CreateTestPlatform() override {
        return std::make_unique<DawnCachingMockPlatform>(&mMockCache);
    }

    NiceMock<CachingInterfaceMock> mMockCache;
};

// Tests that shader module creation works fine even if the cache is disabled.
// Note: This tests needs to use more than 1 device since the frontend cache on each device
//   will prevent going out to the blob cache.
TEST_P(ShaderModuleCachingTests, ShaderModuleNoCache) {
    mMockCache.Disable();

    // First time should create and since cache is disabled, it should not write out to the
    // cache.
    {
        wgpu::Device device = CreateDevice();
        EXPECT_CACHE_STATS(mMockCache, Hit(0u), Add(0u),
                           utils::CreateShaderModule(device, kComputeShaderDefault.data()));
    }

    // Second time should create fine with no cache hits since cache is disabled.
    {
        wgpu::Device device = CreateDevice();
        EXPECT_CACHE_STATS(mMockCache, Hit(0u), Add(0u),
                           utils::CreateShaderModule(device, kComputeShaderDefault.data()));
    }
}

// Tests that shader module creation on the same device uses frontend cache when possible.
TEST_P(ShaderModuleCachingTests, ShaderModuleFrontedCache) {
    // First creation should create a cache entry.
    wgpu::ShaderModule shaderModule;
    EXPECT_CACHE_STATS(
        mMockCache, Hit(0u), Add(1u),
        shaderModule = utils::CreateShaderModule(device, kComputeShaderDefault.data()));

    // Second creation on the same device should just return from frontend cache and should not
    // call out to the blob cache.
    EXPECT_CALL(mMockCache, LoadData).Times(0);
    wgpu::ShaderModule sameShaderModule;
    EXPECT_CACHE_STATS(
        mMockCache, Hit(0u), Add(0u),
        sameShaderModule = utils::CreateShaderModule(device, kComputeShaderDefault.data()));

    EXPECT_EQ(shaderModule.Get() == sameShaderModule.Get(), !UsesWire());
}

// Tests that shader module creation hits the cache when it is enabled.
// Note: This test needs to use more than 1 device since the frontend cache on each device
//   will prevent going out to the blob cache.
TEST_P(ShaderModuleCachingTests, ShaderModuleBlobCache) {
    // First time should create and write out to the blob cache.
    {
        wgpu::Device device = CreateDevice();
        EXPECT_CACHE_STATS(mMockCache, Hit(0u), Add(1u),
                           utils::CreateShaderModule(device, kComputeShaderDefault.data()));
    }

    // Second time should create shader module using the blob cache.
    {
        wgpu::Device device = CreateDevice();
        EXPECT_CACHE_STATS(mMockCache, Hit(1u), Add(0u),
                           utils::CreateShaderModule(device, kComputeShaderDefault.data()));
    }
}

// Tests that shader module creation wouldn't hit the cache if the shader modules are not exactly
// the same.
TEST_P(ShaderModuleCachingTests, DifferentShaderModuleBlobCache) {
    // First time should create and write out to the cache.
    {
        wgpu::Device device = CreateDevice();
        EXPECT_CACHE_STATS(mMockCache, Hit(0u), Add(1u),
                           utils::CreateShaderModule(device, kComputeShaderDefault.data()));
    }

    // Cache should not hit: different shader module.
    {
        wgpu::Device device = CreateDevice();
        EXPECT_CACHE_STATS(
            mMockCache, Hit(0u), Add(1u),
            utils::CreateShaderModule(device, kComputeShaderMultipleEntryPoints.data()));
    }
}

// Tests that shader module creation does not hits the cache when it is enabled but we use different
// isolation keys.
TEST_P(ShaderModuleCachingTests, ShaderModuleBlobCacheIsolationKey) {
    // First time should create and write out to the cache.
    {
        wgpu::Device device = CreateDevice("isolation key 1");
        EXPECT_CACHE_STATS(mMockCache, Hit(0u), Add(1u),
                           utils::CreateShaderModule(device, kComputeShaderDefault.data()));
    }

    // Second time should also create and write out to the cache.
    {
        wgpu::Device device = CreateDevice("isolation key 2");
        EXPECT_CACHE_STATS(mMockCache, Hit(0u), Add(1u),
                           utils::CreateShaderModule(device, kComputeShaderDefault.data()));
    }
}

DAWN_INSTANTIATE_TEST(ShaderModuleCachingTests,
                      D3D11Backend({"blob_cache_hash_validation"}),
                      D3D11Backend({}, {"blob_cache_hash_validation"}),
                      D3D12Backend({"blob_cache_hash_validation"}),
                      D3D12Backend({}, {"blob_cache_hash_validation"}),
                      D3D12Backend({"use_dxc", "blob_cache_hash_validation"}),
                      D3D12Backend({"use_dxc"}, {"blob_cache_hash_validation"}),
                      MetalBackend({"blob_cache_hash_validation"}),
                      MetalBackend({}, {"blob_cache_hash_validation"}),
                      OpenGLBackend({"blob_cache_hash_validation"}),
                      OpenGLBackend({}, {"blob_cache_hash_validation"}),
                      OpenGLESBackend({"blob_cache_hash_validation"}),
                      OpenGLESBackend({}, {"blob_cache_hash_validation"}),
                      VulkanBackend({"blob_cache_hash_validation"}),
                      VulkanBackend({}, {"blob_cache_hash_validation"}),
                      WebGPUBackend({"blob_cache_hash_validation"}),
                      WebGPUBackend({}, {"blob_cache_hash_validation"}));

}  // anonymous namespace
}  // namespace dawn
