/*-------------------------------------------------------------------------
 * 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 Buffer Object Query tests.
 *//*--------------------------------------------------------------------*/

#include "es3fBufferObjectQueryTests.hpp"
#include "glsStateQueryUtil.hpp"
#include "es3fApiCase.hpp"
#include "gluRenderContext.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "deRandom.hpp"
#include "deMath.h"

#include <limits>

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


namespace deqp
{
namespace gles3
{
namespace Functional
{
namespace BufferParamVerifiers
{

void checkIntEquals (tcu::TestContext& testCtx, GLint got, GLint expected)
{
	using tcu::TestLog;

	if (got != expected)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
	}
}

void checkPointerEquals (tcu::TestContext& testCtx, const void* got, const void* expected)
{
	using tcu::TestLog;

	if (got != expected)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: Expected " << expected << "; got " << got << TestLog::EndMessage;
		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "got invalid value");
	}
}

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

	const char*			getTestNamePostfix		(void) const;

	virtual void		verifyInteger			(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)	= DE_NULL;
	virtual void		verifyInteger64			(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference)	= DE_NULL;
private:
	const char*	const	m_testNamePostfix;
};

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

BufferParamVerifier::~BufferParamVerifier ()
{
}

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

class GetBufferParameterIVerifier : public BufferParamVerifier
{
public:
			GetBufferParameterIVerifier	(const glw::Functions& gl, tcu::TestLog& log);

	void	verifyInteger								(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference);
	void	verifyInteger64								(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference);
};

GetBufferParameterIVerifier::GetBufferParameterIVerifier (const glw::Functions& gl, tcu::TestLog& log)
	: BufferParamVerifier(gl, log, "_getbufferparameteri")
{
}

void GetBufferParameterIVerifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint> state;
	glGetBufferParameteriv(target, name, &state);

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

	if (state != reference)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
	}
}

void GetBufferParameterIVerifier::verifyInteger64 (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint> state;
	glGetBufferParameteriv(target, 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 (!de::inRange(reference, (GLint64)std::numeric_limits<GLint>::min(), (GLint64)std::numeric_limits<GLint>::max()))
		return;

	if (state != reference)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
	}
}

class GetBufferParameterI64Verifier : public BufferParamVerifier
{
public:
			GetBufferParameterI64Verifier	(const glw::Functions& gl, tcu::TestLog& log);

	void	verifyInteger					(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference);
	void	verifyInteger64					(tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference);
};

GetBufferParameterI64Verifier::GetBufferParameterI64Verifier (const glw::Functions& gl, tcu::TestLog& log)
	: BufferParamVerifier(gl, log, "_getbufferparameteri64")
{
}

void GetBufferParameterI64Verifier::verifyInteger (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint64> state;
	glGetBufferParameteri64v(target, name, &state);

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

	if (state != reference)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
	}
}

void GetBufferParameterI64Verifier::verifyInteger64 (tcu::TestContext& testCtx, GLenum target, GLenum name, GLint64 reference)
{
	using tcu::TestLog;

	StateQueryMemoryWriteGuard<GLint64> state;
	glGetBufferParameteri64v(target, name, &state);

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

	if (state != reference)
	{
		testCtx.getLog() << TestLog::Message << "// ERROR: expected " << reference << "; got " << state << TestLog::EndMessage;

		if (testCtx.getTestResult() == QP_TEST_RESULT_PASS)
			testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got invalid value");
	}
}


} // BufferParamVerifiers

namespace
{

using namespace BufferParamVerifiers;

// Tests

class BufferCase : public ApiCase
{
public:
	BufferCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
		: ApiCase			(context, name, description)
		, m_bufferTarget	(0)
		, m_verifier		(verifier)
		, m_testAllTargets	(false)
	{
	}

	virtual void testBuffer (void) = DE_NULL;

	void test (void)
	{
		const GLenum bufferTargets[] =
		{
			GL_ARRAY_BUFFER, GL_COPY_READ_BUFFER,
			GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER,

			GL_COPY_WRITE_BUFFER, GL_ELEMENT_ARRAY_BUFFER,
			GL_PIXEL_PACK_BUFFER, GL_PIXEL_UNPACK_BUFFER
		};

		// most test need only to be run with a subset of targets
		const int targets = m_testAllTargets ? DE_LENGTH_OF_ARRAY(bufferTargets) : 4;

		for (int ndx = 0; ndx < targets; ++ndx)
		{
			m_bufferTarget = bufferTargets[ndx];

			GLuint bufferId = 0;
			glGenBuffers(1, &bufferId);
			glBindBuffer(m_bufferTarget, bufferId);
			expectError(GL_NO_ERROR);

			testBuffer();

			glDeleteBuffers(1, &bufferId);
			expectError(GL_NO_ERROR);
		}
	}

protected:
	GLenum					m_bufferTarget;
	BufferParamVerifier*	m_verifier;
	bool					m_testAllTargets;
};

class BufferSizeCase : public BufferCase
{
public:
	BufferSizeCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
		: BufferCase(context, verifier, name, description)
	{
		m_testAllTargets = true;
	}

	void testBuffer (void)
	{
		de::Random rnd(0xabcdef);

		m_verifier->verifyInteger64(m_testCtx, m_bufferTarget, GL_BUFFER_SIZE, 0);

		const int numIterations = 16;
		for (int i = 0; i < numIterations; ++i)
		{
			const GLint len = rnd.getInt(0, 1024);
			glBufferData(m_bufferTarget, len, DE_NULL, GL_STREAM_DRAW);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger64(m_testCtx, m_bufferTarget, GL_BUFFER_SIZE, len);
			expectError(GL_NO_ERROR);
		}
	}
};

class BufferUsageCase : public BufferCase
{
public:
	BufferUsageCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
		: BufferCase(context, verifier, name, description)
	{
	}

	void testBuffer (void)
	{
		m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_USAGE, GL_STATIC_DRAW);

		const GLenum usages[] =
		{
			GL_STREAM_DRAW, GL_STREAM_READ,
			GL_STREAM_COPY, GL_STATIC_DRAW,
			GL_STATIC_READ, GL_STATIC_COPY,
			GL_DYNAMIC_DRAW, GL_DYNAMIC_READ,
			GL_DYNAMIC_COPY
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(usages); ++ndx)
		{
			glBufferData(m_bufferTarget, 16, DE_NULL, usages[ndx]);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_USAGE, usages[ndx]);
			expectError(GL_NO_ERROR);
		}
	}
};

class BufferAccessFlagsCase : public BufferCase
{
public:
	BufferAccessFlagsCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
		: BufferCase(context, verifier, name, description)
	{
	}

	void testBuffer (void)
	{
		m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_ACCESS_FLAGS, 0);

		const GLenum accessFlags[] =
		{
			GL_MAP_READ_BIT,

			GL_MAP_WRITE_BIT,
			GL_MAP_WRITE_BIT																	| GL_MAP_INVALIDATE_RANGE_BIT,
			GL_MAP_WRITE_BIT																									| GL_MAP_INVALIDATE_BUFFER_BIT,
			GL_MAP_WRITE_BIT																	| GL_MAP_INVALIDATE_RANGE_BIT	| GL_MAP_INVALIDATE_BUFFER_BIT,

			GL_MAP_WRITE_BIT									| GL_MAP_FLUSH_EXPLICIT_BIT,
			GL_MAP_WRITE_BIT									| GL_MAP_FLUSH_EXPLICIT_BIT		| GL_MAP_INVALIDATE_RANGE_BIT,
			GL_MAP_WRITE_BIT									| GL_MAP_FLUSH_EXPLICIT_BIT										| GL_MAP_INVALIDATE_BUFFER_BIT,
			GL_MAP_WRITE_BIT									| GL_MAP_FLUSH_EXPLICIT_BIT		| GL_MAP_INVALIDATE_RANGE_BIT	| GL_MAP_INVALIDATE_BUFFER_BIT,

			GL_MAP_WRITE_BIT	| GL_MAP_UNSYNCHRONIZED_BIT,
			GL_MAP_WRITE_BIT	| GL_MAP_UNSYNCHRONIZED_BIT										| GL_MAP_INVALIDATE_RANGE_BIT,
			GL_MAP_WRITE_BIT	| GL_MAP_UNSYNCHRONIZED_BIT																		| GL_MAP_INVALIDATE_BUFFER_BIT,
			GL_MAP_WRITE_BIT	| GL_MAP_UNSYNCHRONIZED_BIT										| GL_MAP_INVALIDATE_RANGE_BIT	| GL_MAP_INVALIDATE_BUFFER_BIT,

			GL_MAP_WRITE_BIT	| GL_MAP_UNSYNCHRONIZED_BIT		| GL_MAP_FLUSH_EXPLICIT_BIT,
			GL_MAP_WRITE_BIT	| GL_MAP_UNSYNCHRONIZED_BIT		| GL_MAP_FLUSH_EXPLICIT_BIT		| GL_MAP_INVALIDATE_RANGE_BIT,
			GL_MAP_WRITE_BIT	| GL_MAP_UNSYNCHRONIZED_BIT		| GL_MAP_FLUSH_EXPLICIT_BIT										| GL_MAP_INVALIDATE_BUFFER_BIT,
			GL_MAP_WRITE_BIT	| GL_MAP_UNSYNCHRONIZED_BIT		| GL_MAP_FLUSH_EXPLICIT_BIT		| GL_MAP_INVALIDATE_RANGE_BIT	| GL_MAP_INVALIDATE_BUFFER_BIT,

		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(accessFlags); ++ndx)
		{
			glBufferData(m_bufferTarget, 16, DE_NULL, GL_DYNAMIC_COPY);
			glMapBufferRange(m_bufferTarget, 0, 16, accessFlags[ndx]);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_ACCESS_FLAGS, accessFlags[ndx]);
			expectError(GL_NO_ERROR);

			glUnmapBuffer(m_bufferTarget);
			expectError(GL_NO_ERROR);
		}
	}
};

class BufferMappedCase : public BufferCase
{
public:
	BufferMappedCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
		: BufferCase(context, verifier, name, description)
	{
	}

	void testBuffer (void)
	{
		m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAPPED, GL_FALSE);

		glBufferData(m_bufferTarget, 16, DE_NULL, GL_DYNAMIC_COPY);
		glMapBufferRange(m_bufferTarget, 0, 16, GL_MAP_WRITE_BIT);
		expectError(GL_NO_ERROR);

		m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAPPED, GL_TRUE);
		expectError(GL_NO_ERROR);

		glUnmapBuffer(m_bufferTarget);
		expectError(GL_NO_ERROR);
	}
};

class BufferOffsetLengthCase : public BufferCase
{
public:
	BufferOffsetLengthCase (Context& context, BufferParamVerifier* verifier, const char* name, const char* description)
		: BufferCase(context, verifier, name, description)
	{
	}

	void testBuffer (void)
	{
		m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAP_OFFSET, 0);
		m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAP_LENGTH, 0);

		glBufferData(m_bufferTarget, 16, DE_NULL, GL_DYNAMIC_COPY);

		const struct BufferRange
		{
			int offset;
			int length;
		} ranges[] =
		{
			{ 0, 16 },
			{ 4, 12 },
			{ 0, 12 },
			{ 8,  8 },
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ranges); ++ndx)
		{
			glMapBufferRange(m_bufferTarget, ranges[ndx].offset, ranges[ndx].length, GL_MAP_WRITE_BIT);
			expectError(GL_NO_ERROR);

			m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAP_OFFSET, ranges[ndx].offset);
			m_verifier->verifyInteger(m_testCtx, m_bufferTarget, GL_BUFFER_MAP_LENGTH, ranges[ndx].length);
			expectError(GL_NO_ERROR);

			glUnmapBuffer(m_bufferTarget);
			expectError(GL_NO_ERROR);
		}
	}
};

class BufferPointerCase : public ApiCase
{
public:
	BufferPointerCase (Context& context, const char* name, const char* description)
		: ApiCase(context, name, description)
	{
	}

	void test (void)
	{
		GLuint bufferId = 0;
		glGenBuffers(1, &bufferId);
		glBindBuffer(GL_ARRAY_BUFFER, bufferId);
		expectError(GL_NO_ERROR);

		StateQueryMemoryWriteGuard<GLvoid*> initialState;
		glGetBufferPointerv(GL_ARRAY_BUFFER, GL_BUFFER_MAP_POINTER, &initialState);
		initialState.verifyValidity(m_testCtx);
		checkPointerEquals(m_testCtx, initialState, 0);

		glBufferData(GL_ARRAY_BUFFER, 8, DE_NULL, GL_DYNAMIC_COPY);
		GLvoid* mapPointer = glMapBufferRange(GL_ARRAY_BUFFER, 0, 8, GL_MAP_READ_BIT);
		expectError(GL_NO_ERROR);

		StateQueryMemoryWriteGuard<GLvoid*> mapPointerState;
		glGetBufferPointerv(GL_ARRAY_BUFFER, GL_BUFFER_MAP_POINTER, &mapPointerState);
		mapPointerState.verifyValidity(m_testCtx);
		checkPointerEquals(m_testCtx, mapPointerState, mapPointer);

		glDeleteBuffers(1, &bufferId);
		expectError(GL_NO_ERROR);
	}
};

} // anonymous

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

BufferObjectQueryTests::BufferObjectQueryTests (Context& context)
	: TestCaseGroup		(context, "buffer_object", "Buffer Object Query tests")
	, m_verifierInt		(DE_NULL)
	, m_verifierInt64	(DE_NULL)
{
}

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

void BufferObjectQueryTests::init (void)
{
	using namespace BufferParamVerifiers;

	DE_ASSERT(m_verifierInt == DE_NULL);
	DE_ASSERT(m_verifierInt64 == DE_NULL);

	m_verifierInt		= new GetBufferParameterIVerifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	m_verifierInt64		= new GetBufferParameterI64Verifier	(m_context.getRenderContext().getFunctions(), m_context.getTestContext().getLog());
	BufferParamVerifier* verifiers[] = {m_verifierInt, m_verifierInt64};

	FOR_EACH_VERIFIER(verifiers, addChild(new BufferSizeCase		(m_context, verifier,	(std::string("buffer_size")				+ verifier->getTestNamePostfix()).c_str(), "BUFFER_SIZE")));
	FOR_EACH_VERIFIER(verifiers, addChild(new BufferUsageCase		(m_context, verifier,	(std::string("buffer_usage")			+ verifier->getTestNamePostfix()).c_str(), "BUFFER_USAGE")));
	FOR_EACH_VERIFIER(verifiers, addChild(new BufferAccessFlagsCase	(m_context, verifier,	(std::string("buffer_access_flags")		+ verifier->getTestNamePostfix()).c_str(), "BUFFER_ACCESS_FLAGS")));
	FOR_EACH_VERIFIER(verifiers, addChild(new BufferMappedCase		(m_context, verifier,	(std::string("buffer_mapped")			+ verifier->getTestNamePostfix()).c_str(), "BUFFER_MAPPED")));
	FOR_EACH_VERIFIER(verifiers, addChild(new BufferOffsetLengthCase(m_context, verifier,	(std::string("buffer_map_offset_length")+ verifier->getTestNamePostfix()).c_str(), "BUFFER_MAP_OFFSET and BUFFER_MAP_LENGTH")));

	addChild(new BufferPointerCase(m_context, "buffer_pointer", "GetBufferPointerv"));
}

void BufferObjectQueryTests::deinit (void)
{
	if (m_verifierInt)
	{
		delete m_verifierInt;
		m_verifierInt = NULL;
	}
	if (m_verifierInt64)
	{
		delete m_verifierInt64;
		m_verifierInt64 = NULL;
	}
}

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