//
// Copyright 2019 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.
//
// EGLCreateContectAttribsTest.cpp:
//   This suite of test cases test invalid attributes passed to eglCreateContext
//   Section 3.7.1 of EGL 1.5 specification provides error cases
//

#include <gtest/gtest.h>
#include <vector>

#include "test_utils/ANGLETest.h"

using namespace angle;

class EGLCreateContextAttribsTest : public ANGLETest
{
  public:
    EGLCreateContextAttribsTest() : mDisplay(EGL_NO_DISPLAY) {}

    void testSetUp() override
    {
        EGLint dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(), EGL_NONE};
        mDisplay           = eglGetPlatformDisplayEXT(
            EGL_PLATFORM_ANGLE_ANGLE, reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
        EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
        EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr) != EGL_FALSE);
    }

    EGLDisplay mDisplay;
};

// Specify invalid client version in the attributes to eglCreateContext
// and verify EGL_BAD_ATTRIBUTE
TEST_P(EGLCreateContextAttribsTest, InvalidClientVersion)
{
    EGLContext context = EGL_NO_CONTEXT;

    // Pick config
    EGLConfig config = EGL_NO_CONFIG_KHR;
    EGLint count     = 0;

    // Get a 1.0 compatible config
    EGLint cfgAttribList1[] = {EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE};
    EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, cfgAttribList1, &config, 1, &count));
    ANGLE_SKIP_TEST_IF(count == 0);

    // GLES 0.0 is invalid verify invalid attribute request
    EGLint contextAttribs1[] = {EGL_CONTEXT_MAJOR_VERSION, 0, EGL_CONTEXT_MINOR_VERSION, 0,
                                EGL_NONE};
    context                  = eglCreateContext(mDisplay, config, nullptr, contextAttribs1);
    EXPECT_EQ(context, EGL_NO_CONTEXT);
    ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);

    // Get a 2.0/3.x compatible config
    EGLint cfgAttribList2[] = {EGL_RENDERABLE_TYPE, (EGL_OPENGL_ES2_BIT), EGL_NONE};
    EXPECT_EGL_TRUE(eglChooseConfig(mDisplay, cfgAttribList2, &config, 1, &count));
    ASSERT_TRUE(count > 0);

    // GLES 2.1 is invalid verify invalid attribute request
    EGLint contextAttribs2[] = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 1,
                                EGL_NONE};
    context                  = eglCreateContext(mDisplay, config, nullptr, contextAttribs2);
    EXPECT_EQ(context, EGL_NO_CONTEXT);
    ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);

    // GLES 3.3 is invalid verify invalid attribute request
    EGLint contextAttribs3[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, 3,
                                EGL_NONE};
    context                  = eglCreateContext(mDisplay, config, nullptr, contextAttribs3);
    EXPECT_EQ(context, EGL_NO_CONTEXT);
    ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);

    // GLES 4.0 is invalid verify invalid attribute request
    EGLint contextAttribs4[] = {EGL_CONTEXT_MAJOR_VERSION, 4, EGL_CONTEXT_MINOR_VERSION, 0,
                                EGL_NONE};
    context                  = eglCreateContext(mDisplay, config, nullptr, contextAttribs4);
    EXPECT_EQ(context, EGL_NO_CONTEXT);
    ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);

    // Cleanup contexts
    eglTerminate(mDisplay);
}

// Choose config that doesn't support requested client version, and verify that eglCreateContext
// sets EGL_BAD_MATCH
TEST_P(EGLCreateContextAttribsTest, IncompatibleConfig)
{
    // Get all the configs
    EGLint count;
    EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, nullptr, 0, &count) != EGL_FALSE);
    EXPECT_TRUE(count > 0);
    std::vector<EGLConfig> configs(count);
    EXPECT_EGL_TRUE(eglGetConfigs(mDisplay, configs.data(), count, &count) != EGL_FALSE);

    EGLConfig notGLES1Config = EGL_NO_CONFIG_KHR;
    EGLConfig notGLES2Config = EGL_NO_CONFIG_KHR;
    EGLConfig notGLES3Config = EGL_NO_CONFIG_KHR;

    // Find non API matching configs
    for (auto config : configs)
    {
        EGLint value = 0;
        EXPECT_EGL_TRUE(eglGetConfigAttrib(mDisplay, config, EGL_RENDERABLE_TYPE, &value));

        if (((value & EGL_OPENGL_ES_BIT) == 0) && (notGLES1Config == EGL_NO_CONFIG_KHR))
        {
            notGLES1Config = config;
            continue;
        }
        if (((value & EGL_OPENGL_ES2_BIT) == 0) && (notGLES2Config == EGL_NO_CONFIG_KHR))
        {
            notGLES2Config = config;
            continue;
        }
        if (((value & EGL_OPENGL_ES3_BIT) == 0) && (notGLES3Config == EGL_NO_CONFIG_KHR))
        {
            notGLES3Config = config;
            continue;
        }
    }

    // These selected configs should not be a match with the requested client version.
    EGLContext context = EGL_NO_CONTEXT;
    // Check GLES1
    if (notGLES1Config != EGL_NO_CONFIG_KHR)
    {
        EGLint contextAttribs1[] = {EGL_CONTEXT_MAJOR_VERSION, 1, EGL_CONTEXT_MINOR_VERSION, 0,
                                    EGL_NONE};
        context = eglCreateContext(mDisplay, notGLES1Config, nullptr, contextAttribs1);
        EXPECT_EQ(context, EGL_NO_CONTEXT);
        ASSERT_EGL_ERROR(EGL_BAD_MATCH);
    }

    // Check GLES2
    if (notGLES2Config != EGL_NO_CONFIG_KHR)
    {
        EGLint contextAttribs2[] = {EGL_CONTEXT_MAJOR_VERSION, 2, EGL_CONTEXT_MINOR_VERSION, 0,
                                    EGL_NONE};
        context = eglCreateContext(mDisplay, notGLES2Config, nullptr, contextAttribs2);
        EXPECT_EQ(context, EGL_NO_CONTEXT);
        ASSERT_EGL_ERROR(EGL_BAD_MATCH);
    }

    // Check GLES3
    if (notGLES3Config != EGL_NO_CONFIG_KHR)
    {
        EGLint contextAttribs3[] = {EGL_CONTEXT_MAJOR_VERSION, 3, EGL_CONTEXT_MINOR_VERSION, 0,
                                    EGL_NONE};
        context = eglCreateContext(mDisplay, notGLES3Config, nullptr, contextAttribs3);
        EXPECT_EQ(context, EGL_NO_CONTEXT);
        ASSERT_EGL_ERROR(EGL_BAD_MATCH);
    }

    // Cleanup contexts
    eglTerminate(mDisplay);
}

ANGLE_INSTANTIATE_TEST(EGLCreateContextAttribsTest,
                       WithNoFixture(ES2_D3D9()),
                       WithNoFixture(ES2_D3D11()),
                       WithNoFixture(ES2_OPENGL()),
                       WithNoFixture(ES2_VULKAN()),
                       WithNoFixture(ES3_D3D11()),
                       WithNoFixture(ES3_OPENGL()),
                       WithNoFixture(ES3_VULKAN()));
