//
// Copyright (c) 2014 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.
//

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "libANGLE/AttributeMap.h"
#include "libANGLE/Config.h"

// Create a generic, valid EGL config that can be modified to test sorting and
// filtering routines
static egl::Config GenerateGenericConfig()
{
    egl::Config config;

    config.bufferSize = 24;
    config.redSize = 8;
    config.greenSize = 8;
    config.blueSize = 8;
    config.luminanceSize = 0;
    config.alphaSize = 8;
    config.alphaMaskSize = 0;
    config.bindToTextureRGB = EGL_TRUE;
    config.bindToTextureRGBA = EGL_TRUE;
    config.colorBufferType = EGL_RGB_BUFFER;
    config.configCaveat = EGL_NONE;
    config.configID = 0;
    config.conformant = EGL_OPENGL_ES2_BIT;
    config.depthSize = 24;
    config.level = 0;
    config.matchNativePixmap = EGL_NONE;
    config.maxPBufferWidth = 1024;
    config.maxPBufferHeight = 1024;
    config.maxPBufferPixels = config.maxPBufferWidth * config.maxPBufferWidth;
    config.maxSwapInterval = 0;
    config.minSwapInterval = 4;
    config.nativeRenderable = EGL_OPENGL_ES2_BIT;
    config.nativeVisualID = 0;
    config.nativeVisualType = 0;
    config.renderableType = EGL_FALSE;
    config.sampleBuffers = 0;
    config.samples = 0;
    config.stencilSize = 8;
    config.surfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
    config.transparentType = EGL_NONE;
    config.transparentRedValue = 0;
    config.transparentGreenValue = 0;
    config.transparentBlueValue = 0;

    return config;
}

static std::vector<egl::Config> GenerateUniqueConfigs(size_t count)
{
    std::vector<egl::Config> configs;

    for (size_t i = 0; i < count; i++)
    {
        egl::Config config = GenerateGenericConfig();
        config.samples = static_cast<EGLint>(i);
        configs.push_back(config);
    }

    return configs;
}

// Add unique configs to a ConfigSet and expect that the size of the
// set is equal to the number of configs added.
TEST(ConfigSetTest, Size)
{
    egl::ConfigSet set;

    std::vector<egl::Config> uniqueConfigs = GenerateUniqueConfigs(16);
    for (size_t i = 0; i < uniqueConfigs.size(); i++)
    {
        set.add(uniqueConfigs[i]);
        EXPECT_EQ(set.size(), i + 1);
    }
}

// [EGL 1.5] section 3.4:
// EGL_CONFIG_ID is a unique integer identifying different EGLConfigs. Configuration IDs
// must be small positive integers starting at 1 and ID assignment should be compact;
// that is, if there are N EGLConfigs defined by the EGL implementation, their
// configuration IDs should be in the range [1, N].
TEST(ConfigSetTest, IDs)
{
    egl::ConfigSet set;

    std::set<EGLint> ids;

    std::vector<egl::Config> uniqueConfigs = GenerateUniqueConfigs(16);
    for (size_t i = 0; i < uniqueConfigs.size(); i++)
    {
        EGLint id = set.add(uniqueConfigs[i]);

        // Check that the config that was inserted has the ID that was returned
        // by ConfigSet::add
        EXPECT_EQ(id, set.get(id).configID);

        ids.insert(id);
    }

    // Verify configCount unique IDs
    EXPECT_EQ(ids.size(), set.size());

    // Check that there are no gaps and the IDs are in the range [1, N].
    EXPECT_EQ(*std::min_element(ids.begin(), ids.end()), 1);
    EXPECT_EQ(*std::max_element(ids.begin(), ids.end()), static_cast<EGLint>(set.size()));
}

TEST(ConfigSetTest, Filtering_BitSizes)
{
    egl::ConfigSet set;

    struct VariableConfigBitSize
    {
        EGLint Name;
        EGLint(egl::Config::*ConfigMember);
    };

    VariableConfigBitSize testMembers[] = 
    {
        { EGL_RED_SIZE,     &egl::Config::redSize     },
        { EGL_GREEN_SIZE,   &egl::Config::greenSize   },
        { EGL_BLUE_SIZE,    &egl::Config::blueSize    },
        { EGL_ALPHA_SIZE,   &egl::Config::alphaSize   },
        { EGL_DEPTH_SIZE,   &egl::Config::depthSize   },
        { EGL_STENCIL_SIZE, &egl::Config::stencilSize },
    };

    // Generate configsPerType configs with varying bit sizes of each type
    size_t configsPerType = 4;
    for (size_t i = 0; i < ArraySize(testMembers); i++)
    {
        for (size_t j = 0; j < configsPerType; j++)
        {
            egl::Config config = GenerateGenericConfig();

            // Set all the other tested members of this config to 0
            for (size_t k = 0; k < ArraySize(testMembers); k++)
            {
                config.*(testMembers[k].ConfigMember) = 0;
            }

            // Set the tested member of this config to i so it ranges from
            // [1, configsPerType]
            config.*(testMembers[i].ConfigMember) = static_cast<EGLint>(j) + 1;

            set.add(config);
        }
    }

    // for each tested member, filter by it's type and verify that the correct number
    // of results are returned
    for (size_t i = 0; i < ArraySize(testMembers); i++)
    {
        // Start with a filter of 1 to not grab the other members
        for (EGLint j = 0; j < static_cast<EGLint>(configsPerType); j++)
        {
            egl::AttributeMap filter;
            filter.insert(testMembers[i].Name, j + 1);

            std::vector<const egl::Config *> filteredConfigs = set.filter(filter);

            EXPECT_EQ(filteredConfigs.size(), configsPerType - j);
        }
    }
}

// Verify the sorting, [EGL 1.5] section 3.4.1.2 pg 30:
// [configs are sorted] by larger total number of color bits (for an RGB
// color buffer this is the sum of EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE,
// and EGL_ALPHA_SIZE; for a luminance color buffer, the sum of EGL_LUMINANCE_SIZE
// and EGL_ALPHA_SIZE).If the requested number of bits in attrib list for a
// particular color component is 0 or EGL_DONT_CARE, then the number of bits
// for that component is not considered.
TEST(ConfigSetTest, Sorting_BitSizes)
{
    egl::ConfigSet set;
    size_t testConfigCount = 64;
    for (size_t i = 0; i < testConfigCount; i++)
    {
        egl::Config config = GenerateGenericConfig();

        // Give random-ish bit sizes to the config
        config.redSize =   (i *  2) %  3;
        config.greenSize = (i +  5) %  7;
        config.blueSize =  (i +  7) % 11;
        config.alphaSize = (i + 13) % 17;

        set.add(config);
    }

    egl::AttributeMap greaterThan1BitFilter;
    greaterThan1BitFilter.insert(EGL_RED_SIZE, 1);
    greaterThan1BitFilter.insert(EGL_GREEN_SIZE, 1);
    greaterThan1BitFilter.insert(EGL_BLUE_SIZE, 1);
    greaterThan1BitFilter.insert(EGL_ALPHA_SIZE, 1);

    std::vector<const egl::Config *> filteredConfigs = set.filter(greaterThan1BitFilter);
    for (size_t i = 1; i < filteredConfigs.size(); i++)
    {
        const egl::Config &prevConfig = *filteredConfigs[i - 1];
        size_t prevBitCount = prevConfig.redSize +
                              prevConfig.greenSize +
                              prevConfig.blueSize +
                              prevConfig.alphaSize;

        const egl::Config &curConfig = *filteredConfigs[i];
        size_t curBitCount = curConfig.redSize +
                             curConfig.greenSize +
                             curConfig.blueSize +
                             curConfig.alphaSize;

        EXPECT_GE(prevBitCount, curBitCount);
    }
}
