/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * 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.
 *
 *//*!
 * \file
 * \brief Integer64 State Query tests.
 *//*--------------------------------------------------------------------*/

#include "es3fInteger64StateQueryTests.hpp"
#include "glsStateQueryUtil.hpp"
#include "es3fApiCase.hpp"
#include "gluRenderContext.hpp"
#include "tcuRenderTarget.hpp"
#include "glwEnums.hpp"

#include <limits>

using namespace glw; // GLint and other
using deqp::gls::StateQueryUtil::StateQueryMemoryWriteGuard;

namespace deqp
{
namespace gles3
{
namespace Functional
{
namespace Integer64StateQueryVerifiers
{

// StateVerifier

class StateVerifier : protected glu::CallLogWrapper
{
public:
    StateVerifier(const glw::Functions &gl, tcu::TestLog &log, const char *testNamePostfix);
    virtual ~StateVerifier(); // make GCC happy

    const char *getTestNamePostfix(void) const;

    virtual void verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLuint64 reference) = 0;

private:
    const char *const m_testNamePostfix;
};

StateVerifier::StateVerifier(const glw::Functions &gl, tcu::TestLog &log, const char *testNamePostfix)
    : glu::CallLogWrapper(gl, log)
    , m_testNamePostfix(testNamePostfix)
{
    enableLogging(true);
}

StateVerifier::~StateVerifier()
{
}

const char *StateVerifier::getTestNamePostfix(void) const
{
    return m_testNamePostfix;
}

// GetBooleanVerifier

class GetBooleanVerifier : public StateVerifier
{
public:
    GetBooleanVerifier(const glw::Functions &gl, tcu::TestLog &log);
    void verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLuint64 reference);
};

GetBooleanVerifier::GetBooleanVerifier(const glw::Functions &gl, tcu::TestLog &log)
    : StateVerifier(gl, log, "_getboolean")
{
}

void GetBooleanVerifier::verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext &testCtx, GLenum name,
                                                               GLuint64 reference)
{
    using tcu::TestLog;

    StateQueryMemoryWriteGuard<GLboolean> state;
    glGetBooleanv(name, &state);

    if (!state.verifyValidity(testCtx))
        return;

    if (state == GL_TRUE) // state is non-zero, could be greater than reference (correct)
        return;

    if (state == GL_FALSE) // state is zero
    {
        if (reference > 0) // and reference is greater than zero?
        {
            testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE" << TestLog::EndMessage;
            if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
                testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
        }
    }
    else
    {
        testCtx.getLog() << TestLog::Message << "// ERROR: expected GL_TRUE or GL_FALSE" << TestLog::EndMessage;
        if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
            testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid boolean value");
    }
}

//GetIntegerVerifier

class GetIntegerVerifier : public StateVerifier
{
public:
    GetIntegerVerifier(const glw::Functions &gl, tcu::TestLog &log);
    void verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLuint64 reference);
};

GetIntegerVerifier::GetIntegerVerifier(const glw::Functions &gl, tcu::TestLog &log)
    : StateVerifier(gl, log, "_getinteger")
{
}

void GetIntegerVerifier::verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext &testCtx, GLenum name,
                                                               GLuint64 reference)
{
    using tcu::TestLog;

    StateQueryMemoryWriteGuard<GLint> state;
    glGetIntegerv(name, &state);

    if (!state.verifyValidity(testCtx))
        return;

    // check that the converted value would be in the correct range, otherwise checking wont tell us anything
    if (reference > (GLuint64)std::numeric_limits<GLint>::max())
        return;

    if (GLuint(state) < reference)
    {
        testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << reference << "; got "
                         << state << TestLog::EndMessage;
        if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
            testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid integer value");
    }
}

//GetFloatVerifier

class GetFloatVerifier : public StateVerifier
{
public:
    GetFloatVerifier(const glw::Functions &gl, tcu::TestLog &log);
    void verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLuint64 reference);
};

GetFloatVerifier::GetFloatVerifier(const glw::Functions &gl, tcu::TestLog &log) : StateVerifier(gl, log, "_getfloat")
{
}

void GetFloatVerifier::verifyUnsignedInteger64GreaterOrEqual(tcu::TestContext &testCtx, GLenum name, GLuint64 reference)
{
    using tcu::TestLog;

    StateQueryMemoryWriteGuard<GLfloat> state;
    glGetFloatv(name, &state);

    if (!state.verifyValidity(testCtx))
        return;

    if (state < GLfloat(reference))
    {
        testCtx.getLog() << TestLog::Message << "// ERROR: expected greater or equal to " << GLfloat(reference)
                         << "; got " << state << TestLog::EndMessage;
        if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
            testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid float value");
    }
}

} // namespace Integer64StateQueryVerifiers

namespace
{

using namespace Integer64StateQueryVerifiers;

class ConstantMinimumValue64TestCase : public ApiCase
{
public:
    ConstantMinimumValue64TestCase(Context &context, StateVerifier *verifier, const char *name, const char *description,
                                   GLenum targetName, GLuint64 minValue)
        : ApiCase(context, name, description)
        , m_targetName(targetName)
        , m_minValue(minValue)
        , m_verifier(verifier)
    {
    }

    void test(void)
    {
        m_verifier->verifyUnsignedInteger64GreaterOrEqual(m_testCtx, m_targetName, m_minValue);
        expectError(GL_NO_ERROR);
    }

private:
    GLenum m_targetName;
    GLuint64 m_minValue;
    StateVerifier *m_verifier;
};

class MaxCombinedStageUniformComponentsCase : public ApiCase
{
public:
    MaxCombinedStageUniformComponentsCase(Context &context, StateVerifier *verifier, const char *name,
                                          const char *description, GLenum targetName, GLenum targetMaxUniformBlocksName,
                                          GLenum targetMaxUniformComponentsName)
        : ApiCase(context, name, description)
        , m_targetName(targetName)
        , m_targetMaxUniformBlocksName(targetMaxUniformBlocksName)
        , m_targetMaxUniformComponentsName(targetMaxUniformComponentsName)
        , m_verifier(verifier)
    {
    }

    void test(void)
    {
        GLint uniformBlockSize = 0;
        glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &uniformBlockSize);
        expectError(GL_NO_ERROR);

        GLint maxUniformBlocks     = 0;
        GLint maxUniformComponents = 0;
        glGetIntegerv(m_targetMaxUniformBlocksName, &maxUniformBlocks);
        glGetIntegerv(m_targetMaxUniformComponentsName, &maxUniformComponents);
        expectError(GL_NO_ERROR);

        // MAX_stage_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4 + MAX_stage_UNIFORM_COMPONENTS
        const GLuint64 minCombinedUniformComponents =
            GLuint64(maxUniformBlocks) * uniformBlockSize / 4 + maxUniformComponents;

        m_verifier->verifyUnsignedInteger64GreaterOrEqual(m_testCtx, m_targetName, minCombinedUniformComponents);
        expectError(GL_NO_ERROR);
    }

private:
    GLenum m_targetName;
    GLenum m_targetMaxUniformBlocksName;
    GLenum m_targetMaxUniformComponentsName;
    StateVerifier *m_verifier;
};

#define FOR_EACH_VERIFIER(VERIFIERS, CODE_BLOCK)                                                 \
    do                                                                                           \
    {                                                                                            \
        for (int _verifierNdx = 0; _verifierNdx < DE_LENGTH_OF_ARRAY(VERIFIERS); _verifierNdx++) \
        {                                                                                        \
            StateVerifier *verifier = (VERIFIERS)[_verifierNdx];                                 \
            CODE_BLOCK;                                                                          \
        }                                                                                        \
    } while (0)

} // namespace

Integer64StateQueryTests::Integer64StateQueryTests(Context &context)
    : TestCaseGroup(context, "integers64", "Integer (64) Values")
    , m_verifierBoolean(DE_NULL)
    , m_verifierInteger(DE_NULL)
    , m_verifierFloat(DE_NULL)
{
}

Integer64StateQueryTests::~Integer64StateQueryTests(void)
{
    deinit();
}

void Integer64StateQueryTests::init(void)
{
    DE_ASSERT(m_verifierBoolean == DE_NULL);
    DE_ASSERT(m_verifierInteger == DE_NULL);
    DE_ASSERT(m_verifierFloat == DE_NULL);

    m_verifierBoolean =
        new GetBooleanVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
    m_verifierInteger =
        new GetIntegerVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
    m_verifierFloat =
        new GetFloatVerifier(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());

    const struct LimitedStateInteger64
    {
        const char *name;
        const char *description;
        GLenum targetName;
        GLuint64 minValue;
    } implementationLimits[] = {{"max_element_index", "MAX_ELEMENT_INDEX", GL_MAX_ELEMENT_INDEX, 0x00FFFFFF /*2^24-1*/},
                                {"max_server_wait_timeout", "MAX_SERVER_WAIT_TIMEOUT", GL_MAX_SERVER_WAIT_TIMEOUT, 0},
                                {"max_uniform_block_size", "MAX_UNIFORM_BLOCK_SIZE", GL_MAX_UNIFORM_BLOCK_SIZE, 16384}};

    // \note do not check the values with integer64 verifier as that has already been checked in implementation_limits
    StateVerifier *verifiers[] = {m_verifierBoolean, m_verifierInteger, m_verifierFloat};

    for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(implementationLimits); testNdx++)
        FOR_EACH_VERIFIER(
            verifiers, addChild(new ConstantMinimumValue64TestCase(
                           m_context, verifier,
                           (std::string(implementationLimits[testNdx].name) + verifier->getTestNamePostfix()).c_str(),
                           implementationLimits[testNdx].description, implementationLimits[testNdx].targetName,
                           implementationLimits[testNdx].minValue)));

    FOR_EACH_VERIFIER(
        verifiers, addChild(new MaxCombinedStageUniformComponentsCase(
                       m_context, verifier,
                       (std::string("max_combined_vertex_uniform_components") + verifier->getTestNamePostfix()).c_str(),
                       "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS,
                       GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_VERTEX_UNIFORM_COMPONENTS)));
    FOR_EACH_VERIFIER(
        verifiers,
        addChild(new MaxCombinedStageUniformComponentsCase(
            m_context, verifier,
            (std::string("max_combined_fragment_uniform_components") + verifier->getTestNamePostfix()).c_str(),
            "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS,
            GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS)));
}

void Integer64StateQueryTests::deinit(void)
{
    if (m_verifierBoolean)
    {
        delete m_verifierBoolean;
        m_verifierBoolean = DE_NULL;
    }
    if (m_verifierInteger)
    {
        delete m_verifierInteger;
        m_verifierInteger = DE_NULL;
    }
    if (m_verifierFloat)
    {
        delete m_verifierFloat;
        m_verifierFloat = DE_NULL;
    }

    this->TestCaseGroup::deinit();
}

} // namespace Functional
} // namespace gles3
} // namespace deqp
