// 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 <array>
#include <vector>

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

namespace dawn {
namespace {

// Define all component swizzle options to test.
constexpr std::array<wgpu::ComponentSwizzle, 6> kComponentSwizzles = {
    wgpu::ComponentSwizzle::Zero, wgpu::ComponentSwizzle::One, wgpu::ComponentSwizzle::R,
    wgpu::ComponentSwizzle::G,    wgpu::ComponentSwizzle::B,   wgpu::ComponentSwizzle::A};

class TextureComponentSwizzleTest : public DawnTest {
  protected:
    void SetUp() override {
        DawnTest::SetUp();
        DAWN_TEST_UNSUPPORTED_IF(!device.HasFeature(wgpu::FeatureName::TextureComponentSwizzle));

        wgpu::ShaderModule module = utils::CreateShaderModule(device, R"(
            @group(0) @binding(0) var texture : texture_2d<f32>;

            @vertex fn vs_main(@builtin(vertex_index) vertexIndex : u32) -> @builtin(position) vec4f {
                var pos = array<vec2f, 3>(
                    vec2f(-1.0, -1.0),
                    vec2f(-1.0, 3.0),
                    vec2f(3.0, -1.0)
                );
                return vec4f(pos[vertexIndex], 0.0, 1.0);
            }

            @fragment fn fs_main() -> @location(0) vec4f {
                // textureLoad samples at an integer coordinate and mip level 0.
                return textureLoad(texture, vec2i(0, 0), 0);
            })");

        utils::ComboRenderPipelineDescriptor pipelineDesc;
        pipelineDesc.vertex.module = module;
        pipelineDesc.cFragment.module = module;
        pipeline = device.CreateRenderPipeline(&pipelineDesc);

        wgpu::TextureDescriptor outputTextureDesc = {};
        outputTextureDesc.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        outputTextureDesc.size = {1, 1, 1};
        outputTextureDesc.format = wgpu::TextureFormat::RGBA8Unorm;
        outputTexture = device.CreateTexture(&outputTextureDesc);
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        std::vector<wgpu::FeatureName> requiredFeatures = {};
        if (SupportsFeatures({wgpu::FeatureName::TextureComponentSwizzle})) {
            requiredFeatures.push_back(wgpu::FeatureName::TextureComponentSwizzle);
        }
        return requiredFeatures;
    }

    struct TestParams {
        wgpu::TextureFormat format;
        // Input data for the source texture. Max 4 bytes for convenience.
        std::array<uint8_t, 4> inputData;
        // The expected values (R, G, B, A) that `textureLoad` would produce
        // for this format *before* any swizzling. This accounts for default values
        // for missing channels (e.g., G=0, B=0, A=255 for R8Unorm).
        std::array<uint8_t, 4> baseLoadValues;
    };

    // Calculates the expected value after swizzling and normalization.
    uint8_t GetExpectedValue(wgpu::ComponentSwizzle swizzle,
                             const std::array<uint8_t, 4>& rgbaData) {
        switch (swizzle) {
            case wgpu::ComponentSwizzle::Zero:
                return 0;
            case wgpu::ComponentSwizzle::One:
                return 255;
            case wgpu::ComponentSwizzle::R:
                return rgbaData[0];
            case wgpu::ComponentSwizzle::G:
                return rgbaData[1];
            case wgpu::ComponentSwizzle::B:
                return rgbaData[2];
            case wgpu::ComponentSwizzle::A:
                return rgbaData[3];
            case wgpu::ComponentSwizzle::Undefined:
            default:
                DAWN_UNREACHABLE();
                return 0;
        }
    }

    void RunSwizzleTest(TestParams params,
                        wgpu::Texture inputTexture,
                        wgpu::ComponentSwizzle swizzleRed,
                        wgpu::ComponentSwizzle swizzleGreen,
                        wgpu::ComponentSwizzle swizzleBlue,
                        wgpu::ComponentSwizzle swizzleAlpha) {
        wgpu::TexelCopyTextureInfo dest = {.texture = inputTexture};
        wgpu::TexelCopyBufferLayout dataLayout = {.bytesPerRow = 256, .rowsPerImage = 1};
        wgpu::Extent3D writeSize = {1, 1, 1};
        const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(params.format);
        device.GetQueue().WriteTexture(&dest, params.inputData.data(), bytesPerTexel, &dataLayout,
                                       &writeSize);

        // Create the TextureView for the input texture with the specified swizzle.
        wgpu::TextureViewDescriptor viewDesc = {};
        wgpu::TextureComponentSwizzleDescriptor swizzleDesc = {};
        swizzleDesc.swizzle.r = swizzleRed;
        swizzleDesc.swizzle.g = swizzleGreen;
        swizzleDesc.swizzle.b = swizzleBlue;
        swizzleDesc.swizzle.a = swizzleAlpha;
        viewDesc.nextInChain = &swizzleDesc;
        wgpu::TextureView textureView = inputTexture.CreateView(&viewDesc);

        // Set up bind group using the swizzled texture view.
        wgpu::BindGroup bindGroup =
            utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, textureView}});

        // Issue render commands.
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassDescriptor renderPassDesc = {};
        wgpu::RenderPassColorAttachment colorAttachment = {};
        colorAttachment.view = outputTexture.CreateView();
        colorAttachment.loadOp = wgpu::LoadOp::Clear;
        colorAttachment.storeOp = wgpu::StoreOp::Store;
        colorAttachment.clearValue = {0.0f, 0.0f, 0.0f, 0.0f};
        renderPassDesc.colorAttachmentCount = 1;
        renderPassDesc.colorAttachments = &colorAttachment;

        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDesc);
        pass.SetPipeline(pipeline);
        pass.SetBindGroup(0, bindGroup);
        pass.Draw(3);
        pass.End();

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

        utils::RGBA8 expectedColor =
            utils::RGBA8(GetExpectedValue(swizzleRed, params.baseLoadValues),
                         GetExpectedValue(swizzleGreen, params.baseLoadValues),
                         GetExpectedValue(swizzleBlue, params.baseLoadValues),
                         GetExpectedValue(swizzleAlpha, params.baseLoadValues));
        EXPECT_PIXEL_RGBA8_EQ(expectedColor, outputTexture, 0, 0);
    }

    void RunTest(TestParams params) {
        wgpu::TextureDescriptor textureDesc = {};
        textureDesc.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
        textureDesc.size = {1, 1, 1};
        textureDesc.format = params.format;
        wgpu::Texture inputTexture = device.CreateTexture(&textureDesc);

        for (auto swizzleRed : kComponentSwizzles) {
            RunSwizzleTest(params, inputTexture, swizzleRed, wgpu::ComponentSwizzle::G,
                           wgpu::ComponentSwizzle::B, wgpu::ComponentSwizzle::A);
        }

        for (auto swizzleGreen : kComponentSwizzles) {
            RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::R, swizzleGreen,
                           wgpu::ComponentSwizzle::B, wgpu::ComponentSwizzle::A);
        }

        for (auto swizzleBlue : kComponentSwizzles) {
            RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::R,
                           wgpu::ComponentSwizzle::G, swizzleBlue, wgpu::ComponentSwizzle::A);
        }

        for (auto swizzleAlpha : kComponentSwizzles) {
            RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::R,
                           wgpu::ComponentSwizzle::G, wgpu::ComponentSwizzle::B, swizzleAlpha);
        }
    }

    wgpu::RenderPipeline pipeline;
    wgpu::Texture outputTexture;
};

// Test that texture component swizzle works as expected when the 'texture-component-swizzle'
// feature is enabled. These tests verify each component's swizzle mapping independently
// by using a render shader to read from a swizzled texture and render to a texture.
// Those covers formats with all channels, and formats where some channels are implicitly
// generated (0.0 or 1.0) by `textureLoad` due to the base format missing components.
TEST_P(TextureComponentSwizzleTest, AllChannelsPresent) {
    TestParams params;
    params.format = wgpu::TextureFormat::RGBA8Unorm;
    params.inputData = {255, 128, 64, 0};
    params.baseLoadValues = {255, 128, 64, 0};
    RunTest(params);
}
TEST_P(TextureComponentSwizzleTest, OnlyRedChannelPresent) {
    TestParams params;
    params.format = wgpu::TextureFormat::R8Unorm;
    params.inputData = {128, 0, 0, 0};
    params.baseLoadValues = {128, 0, 0, 255};  // G, B default to 0, A defaults to 255.
    RunTest(params);
}
TEST_P(TextureComponentSwizzleTest, OnlyRedAndGreenChannelPresent) {
    TestParams params;
    params.format = wgpu::TextureFormat::RG8Unorm;
    params.inputData = {128, 64, 0, 0};
    params.baseLoadValues = {128, 64, 0, 255};  // B defaults to 0, A defaults to 255.
    RunTest(params);
}

// Test that custom swizzle correctly reorders texture components and that a subsequent use of the
// default swizzle correctly reverts to the standard component mapping.
TEST_P(TextureComponentSwizzleTest, UseDefaultSwizzleAfterNonDefaultSwizzle) {
    TestParams params;
    params.format = wgpu::TextureFormat::RGBA8Unorm;
    params.inputData = {255, 128, 64, 0};
    params.baseLoadValues = {255, 128, 64, 0};

    wgpu::TextureDescriptor textureDesc = {};
    textureDesc.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
    textureDesc.size = {1, 1, 1};
    textureDesc.format = params.format;
    wgpu::Texture inputTexture = device.CreateTexture(&textureDesc);

    // First, use a non-default swizzle.
    RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::One, wgpu::ComponentSwizzle::One,
                   wgpu::ComponentSwizzle::One, wgpu::ComponentSwizzle::One);

    // Then, use a default swizzle.
    RunSwizzleTest(params, inputTexture, wgpu::ComponentSwizzle::R, wgpu::ComponentSwizzle::G,
                   wgpu::ComponentSwizzle::B, wgpu::ComponentSwizzle::A);
}

DAWN_INSTANTIATE_TEST(TextureComponentSwizzleTest,
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend(),
                      WebGPUBackend());

}  // anonymous namespace
}  // namespace dawn
