/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2015 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 GL_EXT_debug_marker tests
 *//*--------------------------------------------------------------------*/

#include "es2fDebugMarkerTests.hpp"
#include "gluContextInfo.hpp"
#include "gluRenderContext.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "tcuTestLog.hpp"
#include "deRandom.hpp"
#include "deUniquePtr.hpp"

namespace deqp
{
namespace gles2
{
namespace Functional
{

namespace
{

using std::vector;
using tcu::TestLog;

void checkSupport (const glu::ContextInfo& ctxInfo)
{
	if (!ctxInfo.isExtensionSupported("GL_EXT_debug_marker"))
	{
#if (DE_OS == DE_OS_ANDROID)
		TCU_THROW(TestError, "Support for GL_EXT_debug_marker is mandatory on Android");
#else
		TCU_THROW(NotSupportedError, "GL_EXT_debug_marker is not supported");
#endif
	}
	// else no exception thrown
}

class IsSupportedCase : public TestCase
{
public:
	IsSupportedCase (Context& context)
		: TestCase(context, "supported", "Is GL_EXT_debug_marker supported")
	{
	}

	IterateResult iterate (void)
	{
		checkSupport(m_context.getContextInfo());
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "GL_EXT_debug_marker is supported");
		return STOP;
	}
};

void getSimpleRndString (vector<char>& dst, de::Random& rnd, int maxLen)
{
	const char s_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ -_";

	dst.resize(rnd.getInt(0, (int)maxLen));

	for (size_t ndx = 0; ndx < dst.size(); ndx++)
		dst[ndx] = rnd.choose<char>(DE_ARRAY_BEGIN(s_chars), DE_ARRAY_END(s_chars));
}

void getComplexRndString (vector<char>& dst, de::Random& rnd, int maxLen)
{
	dst.resize(rnd.getInt(0, (int)maxLen));

	for (size_t ndx = 0; ndx < dst.size(); ndx++)
		dst[ndx] = (char)rnd.getUint8();
}

enum CallType
{
	CALL_TYPE_PUSH_GROUP	= 0,
	CALL_TYPE_POP_GROUP,
	CALL_TYPE_INSERT_MARKER,

	CALL_TYPE_LAST
};

class RandomCase : public TestCase
{
public:
	RandomCase (Context& context)
		: TestCase(context, "random", "Random GL_EXT_debug_marker usage")
	{
	}

	void init (void)
	{
		checkSupport(m_context.getContextInfo());
	}

	IterateResult iterate (void)
	{
		const glw::Functions&	gl			= m_context.getRenderContext().getFunctions();
		const int				numIters	= 1000;
		const int				maxMsgLen	= 4096;
		de::Random				rnd			(0xaf829c0);

		for (int iterNdx = 0; iterNdx < numIters; iterNdx++)
		{
			const CallType		callType	= CallType(rnd.getInt(0, CALL_TYPE_LAST-1));

			if (callType == CALL_TYPE_PUSH_GROUP || callType == CALL_TYPE_INSERT_MARKER)
			{
				const bool		nullTerminate	= rnd.getBool();
				const bool		passLength		= rnd.getBool();
				const bool		complexMsg		= rnd.getBool();
				vector<char>	message;

				if (complexMsg)
					getComplexRndString(message, rnd, maxMsgLen);
				else
					getSimpleRndString(message, rnd, maxMsgLen);

				if (nullTerminate)
					message.push_back(char(0));

				{
					const glw::GLsizei	length	= passLength ? glw::GLsizei(nullTerminate ? message.size()-1 : message.size()) : 0;

					if (callType == CALL_TYPE_PUSH_GROUP)
						gl.pushGroupMarkerEXT(length, &message[0]);
					else
						gl.insertEventMarkerEXT(length, &message[0]);
				}
			}
			else
				gl.popGroupMarkerEXT();
		}

		GLU_EXPECT_NO_ERROR(gl.getError(), "Debug marker calls must not set error state");

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All calls passed");
		return STOP;
	}
};

class InvalidCase : public TestCase
{
public:
	InvalidCase (Context& context)
		: TestCase(context, "invalid", "Invalid GL_EXT_debug_marker usage")
	{
	}

	void init (void)
	{
		checkSupport(m_context.getContextInfo());
	}

	IterateResult iterate (void)
	{
		const glw::Functions&	gl	= m_context.getRenderContext().getFunctions();

		m_testCtx.getLog() << TestLog::Message << "Note: GL_EXT_debug_marker calls must not report an error even if invalid arguments are supplied." << TestLog::EndMessage;

		gl.pushGroupMarkerEXT(-1, "foo");
		gl.insertEventMarkerEXT(-1, "foo");
		gl.pushGroupMarkerEXT(0, DE_NULL);
		gl.insertEventMarkerEXT(0, DE_NULL);
		gl.pushGroupMarkerEXT(-1, DE_NULL);
		gl.insertEventMarkerEXT(-1, DE_NULL);

		GLU_EXPECT_NO_ERROR(gl.getError(), "Debug marker calls must not set error state");

		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "All calls passed");
		return STOP;
	}
};

} // anonymous

tcu::TestCaseGroup* createDebugMarkerTests (Context& context)
{
	de::MovePtr<tcu::TestCaseGroup>	debugMarkerGroup	(new tcu::TestCaseGroup(context.getTestContext(), "debug_marker", "GL_EXT_debug_marker tests"));

	debugMarkerGroup->addChild(new IsSupportedCase	(context));
	debugMarkerGroup->addChild(new RandomCase		(context));
	debugMarkerGroup->addChild(new InvalidCase		(context));

	return debugMarkerGroup.release();
}

} // Functional
} // gles2
} // deqp
