// 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 "tests/DawnTest.h"

#include "common/DynamicLib.h"
#include "dawn_native/OpenGLBackend.h"
#include "dawn_native/opengl/DeviceGL.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h"

#include <EGL/egl.h>

namespace {

    class EGLFunctions {
      public:
        EGLFunctions() {
#ifdef DAWN_PLATFORM_WINDOWS
            const char* eglLib = "libEGL.dll";
#else
            const char* eglLib = "libEGL.so";
#endif
            EXPECT_TRUE(mlibEGL.Open(eglLib));
            CreateImage = reinterpret_cast<PFNEGLCREATEIMAGEPROC>(LoadProc("eglCreateImage"));
            DestroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEPROC>(LoadProc("eglDestroyImage"));
            GetCurrentContext =
                reinterpret_cast<PFNEGLGETCURRENTCONTEXTPROC>(LoadProc("eglGetCurrentContext"));
            GetCurrentDisplay =
                reinterpret_cast<PFNEGLGETCURRENTDISPLAYPROC>(LoadProc("eglGetCurrentDisplay"));
        }

      private:
        void* LoadProc(const char* name) {
            void* proc = mlibEGL.GetProc(name);
            EXPECT_NE(proc, nullptr);
            return proc;
        }

      public:
        PFNEGLCREATEIMAGEPROC CreateImage;
        PFNEGLDESTROYIMAGEPROC DestroyImage;
        PFNEGLGETCURRENTCONTEXTPROC GetCurrentContext;
        PFNEGLGETCURRENTDISPLAYPROC GetCurrentDisplay;

      private:
        DynamicLib mlibEGL;
    };

    class ScopedEGLImage {
      public:
        ScopedEGLImage(PFNEGLDESTROYIMAGEPROC destroyImage,
                       PFNGLDELETETEXTURESPROC deleteTextures,
                       EGLDisplay display,
                       EGLImage image,
                       GLuint texture)
            : mDestroyImage(destroyImage),
              mDeleteTextures(deleteTextures),
              mDisplay(display),
              mImage(image),
              mTexture(texture) {
        }

        ScopedEGLImage(ScopedEGLImage&& other) {
            if (mImage != nullptr) {
                mDestroyImage(mDisplay, mImage);
            }
            if (mTexture != 0) {
                mDeleteTextures(1, &mTexture);
            }
            mDestroyImage = std::move(other.mDestroyImage);
            mDeleteTextures = std::move(other.mDeleteTextures);
            mDisplay = std::move(other.mDisplay);
            mImage = std::move(other.mImage);
            mTexture = std::move(other.mTexture);
        }

        ~ScopedEGLImage() {
            if (mTexture != 0) {
                mDeleteTextures(1, &mTexture);
            }
            if (mImage != nullptr) {
                mDestroyImage(mDisplay, mImage);
            }
        }

        EGLImage getImage() const {
            return mImage;
        }

        GLuint getTexture() const {
            return mTexture;
        }

      private:
        PFNEGLDESTROYIMAGEPROC mDestroyImage = nullptr;
        PFNGLDELETETEXTURESPROC mDeleteTextures = nullptr;
        EGLDisplay mDisplay = nullptr;
        EGLImage mImage = nullptr;
        GLuint mTexture = 0;
    };

}  // anonymous namespace

class EGLImageTestBase : public DawnTest {
  protected:
    std::vector<const char*> GetRequiredFeatures() override {
        return {"dawn-internal-usages"};
    }

  public:
    ScopedEGLImage CreateEGLImage(uint32_t width,
                                  uint32_t height,
                                  GLenum internalFormat,
                                  GLenum format,
                                  GLenum type,
                                  void* data,
                                  size_t size) {
        dawn_native::opengl::Device* openglDevice =
            reinterpret_cast<dawn_native::opengl::Device*>(device.Get());
        const dawn_native::opengl::OpenGLFunctions& gl = openglDevice->gl;
        GLuint tex;
        gl.GenTextures(1, &tex);
        gl.BindTexture(GL_TEXTURE_2D, tex);
        gl.TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, data);
        EGLAttrib attribs[1] = {EGL_NONE};
        EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(tex);
        EGLDisplay dpy = egl.GetCurrentDisplay();
        EGLContext ctx = egl.GetCurrentContext();
        EGLImage eglImage = egl.CreateImage(dpy, ctx, EGL_GL_TEXTURE_2D, buffer, attribs);
        EXPECT_NE(nullptr, eglImage);

        return ScopedEGLImage(egl.DestroyImage, gl.DeleteTextures, dpy, eglImage, tex);
    }
    wgpu::Texture WrapEGLImage(const wgpu::TextureDescriptor* descriptor, EGLImage eglImage) {
        dawn_native::opengl::ExternalImageDescriptorEGLImage externDesc;
        externDesc.cTextureDescriptor = reinterpret_cast<const WGPUTextureDescriptor*>(descriptor);
        externDesc.image = eglImage;
        WGPUTexture texture = dawn_native::opengl::WrapExternalEGLImage(device.Get(), &externDesc);
        return wgpu::Texture::Acquire(texture);
    }
    EGLFunctions egl;
};

// A small fixture used to initialize default data for the EGLImage validation tests.
// These tests are skipped if the harness is using the wire.
class EGLImageValidationTests : public EGLImageTestBase {
  public:
    EGLImageValidationTests() {
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        descriptor.size = {10, 10, 1};
        descriptor.sampleCount = 1;
        descriptor.mipLevelCount = 1;
        descriptor.usage = wgpu::TextureUsage::RenderAttachment;
    }

    ScopedEGLImage CreateDefaultEGLImage() {
        return CreateEGLImage(10, 10, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, 0);
    }

  protected:
    wgpu::TextureDescriptor descriptor;
};

// Test a successful wrapping of an EGLImage in a texture
TEST_P(EGLImageValidationTests, Success) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    ScopedEGLImage image = CreateDefaultEGLImage();
    wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage());
    ASSERT_NE(texture.Get(), nullptr);
}

// Test a successful wrapping of an EGLImage in a texture with DawnTextureInternalUsageDescriptor
TEST_P(EGLImageValidationTests, SuccessWithInternalUsageDescriptor) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
    descriptor.nextInChain = &internalDesc;
    internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
    internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor;

    ScopedEGLImage image = CreateDefaultEGLImage();
    wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage());
    ASSERT_NE(texture.Get(), nullptr);
}

// Test an error occurs if an invalid sType is the nextInChain
TEST_P(EGLImageValidationTests, InvalidTextureDescriptor) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());

    wgpu::ChainedStruct chainedDescriptor;
    chainedDescriptor.sType = wgpu::SType::SurfaceDescriptorFromWindowsSwapChainPanel;
    descriptor.nextInChain = &chainedDescriptor;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));

    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor dimension isn't 2D
TEST_P(EGLImageValidationTests, InvalidTextureDimension) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.dimension = wgpu::TextureDimension::e3D;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));

    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the texture usage is not RenderAttachment
TEST_P(EGLImageValidationTests, InvalidTextureUsage) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.usage = wgpu::TextureUsage::TextureBinding;

    ScopedEGLImage image = CreateDefaultEGLImage();
    wgpu::Texture texture;
    ASSERT_DEVICE_ERROR(texture = WrapEGLImage(&descriptor, image.getImage()));

    ASSERT_EQ(texture.Get(), nullptr);
    descriptor.usage = wgpu::TextureUsage::StorageBinding;

    ASSERT_DEVICE_ERROR(texture = WrapEGLImage(&descriptor, image.getImage()));

    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor mip level count isn't 1
TEST_P(EGLImageValidationTests, InvalidMipLevelCount) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.mipLevelCount = 2;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor depth isn't 1
TEST_P(EGLImageValidationTests, InvalidDepth) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.size.depthOrArrayLayers = 2;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor sample count isn't 1
TEST_P(EGLImageValidationTests, InvalidSampleCount) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.sampleCount = 4;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor width doesn't match the surface's
TEST_P(EGLImageValidationTests, InvalidWidth) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.size.width = 11;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Test an error occurs if the descriptor height doesn't match the surface's
TEST_P(EGLImageValidationTests, InvalidHeight) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    descriptor.size.height = 11;

    ScopedEGLImage image = CreateDefaultEGLImage();
    ASSERT_DEVICE_ERROR(wgpu::Texture texture = WrapEGLImage(&descriptor, image.getImage()));
    ASSERT_EQ(texture.Get(), nullptr);
}

// Fixture to test using EGLImages through different usages.
// These tests are skipped if the harness is using the wire.
class EGLImageUsageTests : public EGLImageTestBase {
  public:
    // Test that clearing using BeginRenderPass writes correct data in the eglImage.
    void DoClearTest(EGLImage eglImage,
                     GLuint texture,
                     wgpu::TextureFormat format,
                     GLenum glFormat,
                     GLenum glType,
                     void* data,
                     size_t dataSize) {
        dawn_native::opengl::Device* openglDevice =
            reinterpret_cast<dawn_native::opengl::Device*>(device.Get());
        const dawn_native::opengl::OpenGLFunctions& gl = openglDevice->gl;

        // Get a texture view for the eglImage
        wgpu::TextureDescriptor textureDescriptor;
        textureDescriptor.dimension = wgpu::TextureDimension::e2D;
        textureDescriptor.format = format;
        textureDescriptor.size = {1, 1, 1};
        textureDescriptor.sampleCount = 1;
        textureDescriptor.mipLevelCount = 1;
        textureDescriptor.usage = wgpu::TextureUsage::RenderAttachment;

        wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
        textureDescriptor.nextInChain = &internalDesc;
        internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
        internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor;

        wgpu::Texture eglImageTexture = WrapEGLImage(&textureDescriptor, eglImage);
        ASSERT_NE(eglImageTexture, nullptr);

        wgpu::TextureView eglImageView = eglImageTexture.CreateView();

        utils::ComboRenderPassDescriptor renderPassDescriptor({eglImageView}, {});
        renderPassDescriptor.cColorAttachments[0].clearColor = {1 / 255.0f, 2 / 255.0f, 3 / 255.0f,
                                                                4 / 255.0f};

        // Execute commands to clear the eglImage
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDescriptor);
        pass.EndPass();

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

        // Check the correct data was written
        std::vector<uint8_t> result(dataSize);
        GLuint fbo;
        gl.GenFramebuffers(1, &fbo);
        gl.BindFramebuffer(GL_FRAMEBUFFER, fbo);
        gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
                                0);
        gl.ReadPixels(0, 0, 1, 1, glFormat, glType, result.data());
        gl.BindFramebuffer(GL_FRAMEBUFFER, 0);
        gl.DeleteFramebuffers(1, &fbo);
        ASSERT_EQ(0, memcmp(result.data(), data, dataSize));
    }
};

// Test clearing a R8 EGLImage
TEST_P(EGLImageUsageTests, ClearR8EGLImage) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    ScopedEGLImage eglImage = CreateEGLImage(1, 1, GL_R8, GL_RED, GL_UNSIGNED_BYTE, nullptr, 0);

    uint8_t data = 0x01;
    DoClearTest(eglImage.getImage(), eglImage.getTexture(), wgpu::TextureFormat::R8Unorm, GL_RED,
                GL_UNSIGNED_BYTE, &data, sizeof(data));
}

// Test clearing a RG8 EGLImage
TEST_P(EGLImageUsageTests, ClearRG8EGLImage) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    ScopedEGLImage eglImage = CreateEGLImage(1, 1, GL_RG8, GL_RG, GL_UNSIGNED_BYTE, nullptr, 0);

    uint16_t data = 0x0201;
    DoClearTest(eglImage.getImage(), eglImage.getTexture(), wgpu::TextureFormat::RG8Unorm, GL_RG,
                GL_UNSIGNED_BYTE, &data, sizeof(data));
}

// Test clearing an RGBA8 EGLImage
TEST_P(EGLImageUsageTests, ClearRGBA8EGLImage) {
    DAWN_TEST_UNSUPPORTED_IF(UsesWire());
    ScopedEGLImage eglImage = CreateEGLImage(1, 1, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, nullptr, 0);

    uint32_t data = 0x04030201;
    DoClearTest(eglImage.getImage(), eglImage.getTexture(), wgpu::TextureFormat::RGBA8Unorm,
                GL_RGBA, GL_UNSIGNED_BYTE, &data, sizeof(data));
}

DAWN_INSTANTIATE_TEST(EGLImageValidationTests, OpenGLESBackend());
DAWN_INSTANTIATE_TEST(EGLImageUsageTests, OpenGLESBackend());
