// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/common/Assert.h"
#include "dawn/common/Constants.h"
#include "dawn/common/Math.h"
#include "dawn/tests/unittests/validation/ValidationTest.h"
#include "dawn/utils/TestUtils.h"
#include "dawn/utils/TextureUtils.h"
#include "dawn/utils/WGPUHelpers.h"

class CopyTextureForBrowserTest : public ValidationTest {
  protected:
    wgpu::Texture Create2DTexture(uint32_t width,
                                  uint32_t height,
                                  uint32_t mipLevelCount,
                                  uint32_t arrayLayerCount,
                                  wgpu::TextureFormat format,
                                  wgpu::TextureUsage usage,
                                  uint32_t sampleCount = 1) {
        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = width;
        descriptor.size.height = height;
        descriptor.size.depthOrArrayLayers = arrayLayerCount;
        descriptor.sampleCount = sampleCount;
        descriptor.format = format;
        descriptor.mipLevelCount = mipLevelCount;
        descriptor.usage = usage;
        wgpu::Texture tex = device.CreateTexture(&descriptor);
        return tex;
    }

    void TestCopyTextureForBrowser(utils::Expectation expectation,
                                   wgpu::Texture srcTexture,
                                   uint32_t srcLevel,
                                   wgpu::Origin3D srcOrigin,
                                   wgpu::Texture dstTexture,
                                   uint32_t dstLevel,
                                   wgpu::Origin3D dstOrigin,
                                   wgpu::Extent3D extent3D,
                                   wgpu::TextureAspect aspect = wgpu::TextureAspect::All,
                                   wgpu::CopyTextureForBrowserOptions options = {}) {
        wgpu::ImageCopyTexture srcImageCopyTexture =
            utils::CreateImageCopyTexture(srcTexture, srcLevel, srcOrigin, aspect);
        wgpu::ImageCopyTexture dstImageCopyTexture =
            utils::CreateImageCopyTexture(dstTexture, dstLevel, dstOrigin, aspect);

        if (expectation == utils::Expectation::Success) {
            device.GetQueue().CopyTextureForBrowser(&srcImageCopyTexture, &dstImageCopyTexture,
                                                    &extent3D, &options);
        } else {
            ASSERT_DEVICE_ERROR(device.GetQueue().CopyTextureForBrowser(
                &srcImageCopyTexture, &dstImageCopyTexture, &extent3D, &options));
        }
    }
};

// Tests should be Success
TEST_F(CopyTextureForBrowserTest, Success) {
    wgpu::Texture source =
        Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
    wgpu::Texture destination =
        Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);

    // Different copies, including some that touch the OOB condition
    {
        // Copy a region along top left boundary
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1});

        // Copy entire texture
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {16, 16, 1});

        // Copy a region along bottom right boundary
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {8, 8, 0}, destination, 0,
                                  {8, 8, 0}, {8, 8, 1});

        // Copy region into mip
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 2,
                                  {0, 0, 0}, {4, 4, 1});

        // Copy mip into region
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 2, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1});

        // Copy between slices
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 1}, {16, 16, 1});
    }

    // Empty copies are valid
    {
        // An empty copy
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {0, 0, 1});

        // An empty copy with depth = 0
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {0, 0, 0});

        // An empty copy touching the side of the source texture
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {16, 16, 0}, {0, 0, 1});

        // An empty copy touching the side of the destination texture
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {16, 16, 0}, {0, 0, 1});
    }
}

// Test source or destination texture has wrong usages
TEST_F(CopyTextureForBrowserTest, IncorrectUsage) {
    wgpu::Texture validSource =
        Create2DTexture(16, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
    wgpu::Texture validDestination =
        Create2DTexture(16, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);
    wgpu::Texture noSampledUsageSource =
        Create2DTexture(16, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::CopySrc);
    wgpu::Texture noRenderAttachmentUsageDestination =
        Create2DTexture(16, 16, 5, 2, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::CopyDst);
    wgpu::Texture noCopySrcUsageSource = Create2DTexture(
        16, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::TextureBinding);
    wgpu::Texture noCopyDstUsageSource = Create2DTexture(
        16, 16, 5, 2, wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureUsage::RenderAttachment);

    // Incorrect source usage causes failure : lack |Sampled| usage
    TestCopyTextureForBrowser(utils::Expectation::Failure, noSampledUsageSource, 0, {0, 0, 0},
                              validDestination, 0, {0, 0, 0}, {16, 16, 1});

    // Incorrect destination usage causes failure: lack |RenderAttachement| usage.
    TestCopyTextureForBrowser(utils::Expectation::Failure, validSource, 0, {0, 0, 0},
                              noRenderAttachmentUsageDestination, 0, {0, 0, 0}, {16, 16, 1});

    // Incorrect source usage causes failure : lack |CopySrc| usage
    TestCopyTextureForBrowser(utils::Expectation::Failure, noCopySrcUsageSource, 0, {0, 0, 0},
                              validDestination, 0, {0, 0, 0}, {16, 16, 1});

    // Incorrect destination usage causes failure: lack |CopyDst| usage.
    TestCopyTextureForBrowser(utils::Expectation::Failure, validSource, 0, {0, 0, 0},
                              noCopyDstUsageSource, 0, {0, 0, 0}, {16, 16, 1});
}

// Test source or destination texture is destroyed.
TEST_F(CopyTextureForBrowserTest, DestroyedTexture) {
    wgpu::CopyTextureForBrowserOptions options = {};

    // Valid src and dst textures.
    {
        wgpu::Texture source =
            Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                            wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
        wgpu::Texture destination =
            Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                            wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, options);

        // Check noop copy
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {0, 0, 0}, wgpu::TextureAspect::All, options);
    }

    // Destroyed src texture.
    {
        wgpu::Texture source =
            Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                            wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
        wgpu::Texture destination =
            Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                            wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);
        source.Destroy();
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, options);

        // Check noop copy
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {0, 0, 0}, wgpu::TextureAspect::All, options);
    }

    // Destroyed dst texture.
    {
        wgpu::Texture source =
            Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                            wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
        wgpu::Texture destination =
            Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                            wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);

        destination.Destroy();
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, options);

        // Check noop copy
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {0, 0, 0}, wgpu::TextureAspect::All, options);
    }
}

// Test non-zero value origin in source and OOB copy rects.
TEST_F(CopyTextureForBrowserTest, OutOfBounds) {
    wgpu::Texture source =
        Create2DTexture(16, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
    wgpu::Texture destination =
        Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);

    // OOB on source
    {
        // x + width overflows
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {1, 0, 0}, destination, 0,
                                  {0, 0, 0}, {16, 16, 1});

        // y + height overflows
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 1, 0}, destination, 0,
                                  {0, 0, 0}, {16, 16, 1});

        // non-zero mip overflows
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 1, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {9, 9, 1});

        // copy to multiple slices
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 2}, {16, 16, 2});

        // copy origin z value is non-zero.
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 1}, destination, 0,
                                  {0, 0, 2}, {16, 16, 1});
    }

    // OOB on destination
    {
        // x + width overflows
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {1, 0, 0}, {16, 16, 1});

        // y + height overflows
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 1, 0}, {16, 16, 1});

        // non-zero mip overflows
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 1,
                                  {0, 0, 0}, {9, 9, 1});

        // arrayLayer + depth OOB
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 4}, {16, 16, 1});

        // empty copy on non-existent mip fails
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 6,
                                  {0, 0, 0}, {0, 0, 1});

        // empty copy on non-existent slice fails
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 4}, {0, 0, 1});
    }
}

// Test destination texture has format that not supported by CopyTextureForBrowser().
TEST_F(CopyTextureForBrowserTest, InvalidDstFormat) {
    wgpu::Texture source =
        Create2DTexture(16, 16, 5, 1, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
    wgpu::Texture destination =
        Create2DTexture(16, 16, 5, 2, wgpu::TextureFormat::RG8Uint,
                        wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);

    // Not supported dst texture format.
    TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                              {0, 0, 0}, {0, 0, 1});
}

// Test source or destination texture are multisampled.
TEST_F(CopyTextureForBrowserTest, InvalidSampleCount) {
    wgpu::Texture sourceMultiSampled1x =
        Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding, 1);
    wgpu::Texture destinationMultiSampled1x =
        Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 1);
    wgpu::Texture sourceMultiSampled4x =
        Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding, 4);
    wgpu::Texture destinationMultiSampled4x =
        Create2DTexture(16, 16, 1, 1, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment, 4);

    // An empty copy with dst texture sample count > 1 failure.
    TestCopyTextureForBrowser(utils::Expectation::Failure, sourceMultiSampled1x, 0, {0, 0, 0},
                              destinationMultiSampled4x, 0, {0, 0, 0}, {0, 0, 1});

    // A empty copy with source texture sample count > 1 failure
    TestCopyTextureForBrowser(utils::Expectation::Failure, sourceMultiSampled4x, 0, {0, 0, 0},
                              destinationMultiSampled1x, 0, {0, 0, 0}, {0, 0, 1});
}

// Test color space conversion related attributes in CopyTextureForBrowserOptions.
TEST_F(CopyTextureForBrowserTest, ColorSpaceConversion_ColorSpace) {
    wgpu::Texture source =
        Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
    wgpu::Texture destination =
        Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);

    wgpu::CopyTextureForBrowserOptions options = {};
    options.needsColorSpaceConversion = true;

    // Valid cases
    {
        wgpu::CopyTextureForBrowserOptions validOptions = options;
        std::array<float, 7> srcTransferFunctionParameters = {};
        std::array<float, 7> dstTransferFunctionParameters = {};
        std::array<float, 9> conversionMatrix = {};
        validOptions.srcTransferFunctionParameters = srcTransferFunctionParameters.data();
        validOptions.dstTransferFunctionParameters = dstTransferFunctionParameters.data();
        validOptions.conversionMatrix = conversionMatrix.data();
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, validOptions);

        // if no color space conversion, no need to validate related attributes
        wgpu::CopyTextureForBrowserOptions noColorSpaceConversion = options;
        noColorSpaceConversion.needsColorSpaceConversion = false;
        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All,
                                  noColorSpaceConversion);
    }

    // Invalid cases: srcTransferFunctionParameters, dstTransferFunctionParameters or
    // conversionMatrix is nullptr or not set
    {
        // not set srcTransferFunctionParameters
        wgpu::CopyTextureForBrowserOptions invalidOptions = options;
        std::array<float, 7> dstTransferFunctionParameters = {};
        std::array<float, 9> conversionMatrix = {};
        invalidOptions.dstTransferFunctionParameters = dstTransferFunctionParameters.data();
        invalidOptions.conversionMatrix = conversionMatrix.data();
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, invalidOptions);

        // set to nullptr
        invalidOptions.srcTransferFunctionParameters = nullptr;
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, invalidOptions);
    }

    {
        // not set dstTransferFunctionParameters
        wgpu::CopyTextureForBrowserOptions invalidOptions = options;
        std::array<float, 7> srcTransferFunctionParameters = {};
        std::array<float, 9> conversionMatrix = {};
        invalidOptions.srcTransferFunctionParameters = srcTransferFunctionParameters.data();
        invalidOptions.conversionMatrix = conversionMatrix.data();
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, invalidOptions);

        // set to nullptr
        invalidOptions.dstTransferFunctionParameters = nullptr;
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, invalidOptions);
    }

    {
        // not set conversionMatrix
        wgpu::CopyTextureForBrowserOptions invalidOptions = options;
        std::array<float, 7> srcTransferFunctionParameters = {};
        std::array<float, 7> dstTransferFunctionParameters = {};
        invalidOptions.srcTransferFunctionParameters = srcTransferFunctionParameters.data();
        invalidOptions.dstTransferFunctionParameters = dstTransferFunctionParameters.data();
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, invalidOptions);

        // set to nullptr
        invalidOptions.conversionMatrix = nullptr;
        TestCopyTextureForBrowser(utils::Expectation::Failure, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, invalidOptions);
    }
}

// Test option.srcAlphaMode/dstAlphaMode
TEST_F(CopyTextureForBrowserTest, ColorSpaceConversion_TextureAlphaState) {
    wgpu::Texture source =
        Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::TextureBinding);
    wgpu::Texture destination =
        Create2DTexture(16, 16, 5, 4, wgpu::TextureFormat::RGBA8Unorm,
                        wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::RenderAttachment);

    wgpu::CopyTextureForBrowserOptions options = {};

    // Valid src texture alpha state and valid dst texture alpha state
    {
        options.srcAlphaMode = wgpu::AlphaMode::Premultiplied;
        options.dstAlphaMode = wgpu::AlphaMode::Premultiplied;

        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, options);

        options.srcAlphaMode = wgpu::AlphaMode::Premultiplied;
        options.dstAlphaMode = wgpu::AlphaMode::Unpremultiplied;

        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, options);

        options.srcAlphaMode = wgpu::AlphaMode::Unpremultiplied;
        options.dstAlphaMode = wgpu::AlphaMode::Premultiplied;

        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, options);

        options.srcAlphaMode = wgpu::AlphaMode::Unpremultiplied;
        options.dstAlphaMode = wgpu::AlphaMode::Unpremultiplied;

        TestCopyTextureForBrowser(utils::Expectation::Success, source, 0, {0, 0, 0}, destination, 0,
                                  {0, 0, 0}, {4, 4, 1}, wgpu::TextureAspect::All, options);
    }
}
