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

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

namespace dawn {
namespace {

constexpr uint32_t kRTSize = 16;
constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::RGBA8Unorm;

constexpr wgpu::FeatureName kPrimitiveIndexFeature = wgpu::FeatureName::PrimitiveIndex;

using RequirePrimitiveIndexFeature = bool;
DAWN_TEST_PARAM_STRUCT(PrimitiveIndexTestsParams, RequirePrimitiveIndexFeature);

class PrimitiveIndexTests : public DawnTestWithParams<PrimitiveIndexTestsParams> {
  public:
    void SetUp() override {
        DawnTestWithParams<PrimitiveIndexTestsParams>::SetUp();
        // TODO(crbug.com/523134902): Produces incorrect result on Pixel 10.
        DAWN_SUPPRESS_TEST_IF(IsAndroid() && IsImgTec() && IsVulkan());
    }

    wgpu::Texture CreateDefault2DTexture() {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = kRTSize;
        descriptor.size.height = kRTSize;
        descriptor.size.depthOrArrayLayers = 1;
        descriptor.sampleCount = 1;
        descriptor.format = kFormat;
        descriptor.mipLevelCount = 1;
        descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        return device.CreateTexture(&descriptor);
    }

  protected:
    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        mIsPrimitiveIndexSupportedOnAdapter = SupportsFeatures({kPrimitiveIndexFeature});
        if (!mIsPrimitiveIndexSupportedOnAdapter) {
            return {};
        }

        if (GetParam().mRequirePrimitiveIndexFeature) {
            return {kPrimitiveIndexFeature};
        }

        return {};
    }

    bool IsPrimitiveIndexSupportedOnAdapter() const { return mIsPrimitiveIndexSupportedOnAdapter; }

  private:
    bool mIsPrimitiveIndexSupportedOnAdapter = false;
};

// Test simple primitive index within shader with enable directive. The result should be as expected
// if the device enables the extension, otherwise a shader creation error should be caught.
TEST_P(PrimitiveIndexTests, BasicPrimitiveIndexFeaturesTest) {
    // Skip if device doesn't support the extension.
    DAWN_TEST_UNSUPPORTED_IF(!device.HasFeature(kPrimitiveIndexFeature));

    const char* shader = R"(
enable primitive_index;

@vertex
fn VSMain(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
    var pos = array(
        vec2f(-1, -1), vec2f(1, -1), vec2f(-1, 1),
        vec2f(1, 1), vec2f(1, -1), vec2f(-1, 1));

    return vec4f(pos[VertexIndex % 6], 0.0, 1.0);
}

var<private> colorId : array<vec3f, 5> = array<vec3f, 5>(
    vec3f(1, 0, 0),
    vec3f(0, 1, 0),
    vec3f(0, 0, 1),
    vec3f(1, 1, 0),
    vec3f(1, 1, 1)
);

@fragment
fn FSMain(@builtin(primitive_index) pid : u32) -> @location(0) vec4f {
    // Select a color based on the primitive index
    return vec4f(colorId[pid%5], 1.0);
})";

    wgpu::ShaderModule shaderModule = utils::CreateShaderModule(device, shader);

    // Create render pipeline.
    wgpu::RenderPipeline pipeline;
    {
        utils::ComboRenderPipelineDescriptor descriptor;

        descriptor.vertex.module = shaderModule;

        descriptor.cFragment.module = shaderModule;
        descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
        descriptor.cTargets[0].format = kFormat;

        pipeline = device.CreateRenderPipeline(&descriptor);
    }

    wgpu::Texture renderTarget = CreateDefault2DTexture();

    auto drawPrimitives = [&](uint32_t count) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

        {
            // In the render pass we clear renderTarget to black, then draw a colored triangles
            // based on the primitive ID to the top left and bottom right of the rnederTarget.
            utils::ComboRenderPassDescriptor renderPass({renderTarget.CreateView()});
            renderPass.cColorAttachments[0].clearValue = {0.0f, 0.0f, 0.0f, 1.0f};

            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            pass.SetPipeline(pipeline);
            pass.Draw(count * 3);
            pass.End();
        }

        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
    };

    // Draw N primitives and ensure that the color written corresponds to the given primitive ID.
    drawPrimitives(2);
    EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kRed, renderTarget, 1, kRTSize - 1);
    EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kGreen, renderTarget, kRTSize - 1, 1);

    drawPrimitives(4);
    EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kBlue, renderTarget, 1, kRTSize - 1);
    EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kYellow, renderTarget, kRTSize - 1, 1);

    drawPrimitives(6);
    EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kWhite, renderTarget, 1, kRTSize - 1);
    EXPECT_PIXEL_RGBA8_EQ(utils::RGBA8::kRed, renderTarget, kRTSize - 1, 1);
}

// DawnTestBase::CreateDeviceImpl always enables allow_unsafe_apis toggle.
DAWN_INSTANTIATE_TEST_P(PrimitiveIndexTests,
                        {
                            D3D11Backend(),
                            D3D12Backend(),
                            VulkanBackend(),
                            WebGPUBackend(),
                            MetalBackend(),
                            OpenGLBackend(),
                            OpenGLESBackend(),
                        },
                        {true, false});

}  // anonymous namespace
}  // namespace dawn
