//
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// EGLWaylandTest.cpp: tests for EGL_EXT_platform_wayland

#include <gtest/gtest.h>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <wayland-client.h>
#include <wayland-egl-backend.h>

#include "test_utils/ANGLETest.h"
#include "util/linux/wayland/WaylandWindow.h"

using namespace angle;

namespace
{
const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
}

class EGLWaylandTest : public ANGLETest<>
{
  public:
    std::vector<EGLAttrib> getDisplayAttributes() const
    {
        std::vector<EGLAttrib> attribs;

        attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
        attribs.push_back(GetParam().getRenderer());
        attribs.push_back(EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE);
        attribs.push_back(EGL_PLATFORM_WAYLAND_EXT);
        attribs.push_back(EGL_NONE);

        return attribs;
    }

    void testSetUp() override
    {
        if (!IsWaylandWindowAvailable())
        {
            GTEST_SKIP() << "Wayland window unavailable.";
        }

        mOsWindow = CreateWaylandWindow(nullptr);
        ASSERT_TRUE(mOsWindow->initialize("EGLWaylandTest", 500, 500));
        setWindowVisible(mOsWindow, true);

        EGLNativeDisplayType waylandDisplay = mOsWindow->getNativeDisplay();
        std::vector<EGLAttrib> attribs      = getDisplayAttributes();
        mDisplay = eglGetPlatformDisplay(GetEglPlatform(), (void *)waylandDisplay, attribs.data());
        ASSERT_NE(EGL_NO_DISPLAY, mDisplay);

        ASSERT_TRUE(EGL_TRUE == eglInitialize(mDisplay, nullptr, nullptr));

        int nConfigs = 0;
        ASSERT_TRUE(EGL_TRUE == eglGetConfigs(mDisplay, nullptr, 0, &nConfigs));
        ASSERT_GE(nConfigs, 1);

        int nReturnedConfigs = 0;
        mConfigs.resize(nConfigs);
        ASSERT_TRUE(EGL_TRUE ==
                    eglGetConfigs(mDisplay, mConfigs.data(), nConfigs, &nReturnedConfigs));
        ASSERT_EQ(nConfigs, nReturnedConfigs);
    }

    void testTearDown() override
    {
        mConfigs.clear();
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglTerminate(mDisplay);
        if (mOsWindow != nullptr)
        {
            OSWindow::Delete(&mOsWindow);
        }
    }

    OSWindow *mOsWindow = nullptr;
    EGLDisplay mDisplay = EGL_NO_DISPLAY;
    std::vector<EGLConfig> mConfigs;
};

// Test that a Wayland window can be created and used for rendering
TEST_P(EGLWaylandTest, WaylandWindowRendering)
{
    for (EGLConfig config : mConfigs)
    {
        // Finally, try to do a clear on the window.
        EGLContext context = eglCreateContext(mDisplay, config, EGL_NO_CONTEXT, contextAttribs);
        ASSERT_NE(EGL_NO_CONTEXT, context);

        EGLSurface window =
            eglCreateWindowSurface(mDisplay, config, mOsWindow->getNativeWindow(), nullptr);
        ASSERT_EGL_SUCCESS();

        eglMakeCurrent(mDisplay, window, window, context);
        ASSERT_EGL_SUCCESS();

        glViewport(0, 0, 500, 500);
        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        ASSERT_GL_NO_ERROR();
        EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);

        // Teardown
        eglDestroySurface(mDisplay, window);
        ASSERT_EGL_SUCCESS();

        eglDestroyContext(mDisplay, context);
        ASSERT_EGL_SUCCESS();

        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        ASSERT_EGL_SUCCESS();
    }
}

// Test that a Wayland window can swap buffers multiple times with no issues
TEST_P(EGLWaylandTest, SwapBuffers)
{
    for (EGLConfig config : mConfigs)
    {
        EGLContext context = eglCreateContext(mDisplay, config, EGL_NO_CONTEXT, contextAttribs);
        ASSERT_NE(EGL_NO_CONTEXT, context);

        EGLSurface surface =
            eglCreateWindowSurface(mDisplay, config, mOsWindow->getNativeWindow(), nullptr);
        ASSERT_EGL_SUCCESS();

        eglMakeCurrent(mDisplay, surface, surface, context);
        ASSERT_EGL_SUCCESS();

        const uint32_t loopcount = 16;
        for (uint32_t i = 0; i < loopcount; i++)
        {
            mOsWindow->messageLoop();

            glViewport(0, 0, 500, 500);
            glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            ASSERT_GL_NO_ERROR() << "glClear failed";
            EXPECT_PIXEL_EQ(250, 250, 0, 0, 255, 255);

            eglSwapBuffers(mDisplay, surface);
            ASSERT_EGL_SUCCESS() << "eglSwapBuffers failed.";
        }

        // Teardown
        eglDestroySurface(mDisplay, surface);
        ASSERT_EGL_SUCCESS();

        eglDestroyContext(mDisplay, context);
        ASSERT_EGL_SUCCESS();

        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        ASSERT_EGL_SUCCESS();
    }
}

ANGLE_INSTANTIATE_TEST(EGLWaylandTest, WithNoFixture(ES2_VULKAN()));
