#ifndef _GLSLONGSTRESSCASE_HPP
#define _GLSLONGSTRESSCASE_HPP
/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) 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 Parametrized, long-running stress case.
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "tcuTestCase.hpp"
#include "tcuTexture.hpp"
#include "tcuMatrix.hpp"
#include "gluRenderContext.hpp"
#include "gluShaderUtil.hpp"
#include "glsTextureTestUtil.hpp"
#include "deRandom.hpp"
#include "deSharedPtr.hpp"

#include <string>
#include <vector>
#include <map>

namespace deqp
{
namespace gls
{

namespace LongStressCaseInternal
{

template <typename T> class GLObjectManager;
class Program;
class Buffer;
class Texture;
class DebugInfoRenderer;

}

struct VarSpec
{
	union Value
	{
		float	f[4*4]; // \note Matrices are stored in column major order.
		int		i[4];
	};

	std::string		name;
	glu::DataType	type;
	Value			minValue;
	Value			maxValue;

	template <typename T>
	VarSpec (const std::string& name_, const T& minValue_, const T& maxValue_)	: name(name_) { set(minValue_, maxValue_); }

	template <typename T>
	VarSpec (const std::string& name_, const T& value)							: name(name_) { set(value, value); }

	void set (float minValue_, float maxValue_)
	{
		type			= glu::TYPE_FLOAT;
		minValue.f[0]	= minValue_;
		maxValue.f[0]	= maxValue_;
	}

	template <int ValSize>
	void set (const tcu::Vector<float, ValSize>& minValue_, const tcu::Vector<float, ValSize>& maxValue_)
	{
		type = glu::getDataTypeFloatVec(ValSize);
		vecToArr(minValue_, minValue.f);
		vecToArr(maxValue_, maxValue.f);
	}

	template <int ValRows, int ValCols>
	void set (const tcu::Matrix<float, ValRows, ValCols>& minValue_, const tcu::Matrix<float, ValRows, ValCols>& maxValue_)
	{
		type = glu::getDataTypeMatrix(ValCols, ValRows);
		matToArr(minValue_, minValue.f);
		matToArr(maxValue_, maxValue.f);
	}

	void set (int minValue_, int maxValue_)
	{
		type			= glu::TYPE_INT;
		minValue.i[0]	= minValue_;
		maxValue.i[0]	= maxValue_;
	}

	template <int ValSize>
	void set (const tcu::Vector<int, ValSize>& minValue_, const tcu::Vector<int, ValSize>& maxValue_)
	{
		type = glu::getDataTypeVector(glu::TYPE_INT, ValSize);
		vecToArr(minValue_, minValue.i);
		vecToArr(maxValue_, maxValue.i);
	}

private:
	template <typename T, int SrcSize, int DstSize>
	static inline void vecToArr (const tcu::Vector<T, SrcSize>& src, T (&dst)[DstSize])
	{
		DE_STATIC_ASSERT(DstSize >= SrcSize);
		for (int i = 0; i < SrcSize; i++)
			dst[i] = src[i];
	}

	template <int ValRows, int ValCols, int DstSize>
	static inline void matToArr (const tcu::Matrix<float, ValRows, ValCols>& src, float (&dst)[DstSize])
	{
		DE_STATIC_ASSERT(DstSize >= ValRows*ValCols);
		tcu::Array<float, ValRows*ValCols> data = src.getColumnMajorData();
		for (int i = 0; i < ValRows*ValCols; i++)
			dst[i] = data[i];
	}
};

struct TextureSpec
{
	glu::TextureTestUtil::TextureType	textureType;
	deUint32							textureUnit;
	int									width;
	int									height;
	deUint32							format;
	deUint32							dataType;
	deUint32							internalFormat;
	bool								useMipmap;
	deUint32							minFilter;
	deUint32							magFilter;
	deUint32							sWrap;
	deUint32							tWrap;
	tcu::Vec4							minValue;
	tcu::Vec4							maxValue;

	TextureSpec (const glu::TextureTestUtil::TextureType	texType,
				 const deUint32								unit,
				 const int									width_,
				 const int									height_,
				 const deUint32								format_,
				 const deUint32								dataType_,
				 const deUint32								internalFormat_,
				 const bool									useMipmap_,
				 const deUint32								minFilter_,
				 const deUint32								magFilter_,
				 const deUint32								sWrap_,
				 const deUint32								tWrap_,
				 const tcu::Vec4&							minValue_,
				 const tcu::Vec4&							maxValue_)
		: textureType		(texType)
		, textureUnit		(unit)
		, width				(width_)
		, height			(height_)
		, format			(format_)
		, dataType			(dataType_)
		, internalFormat	(internalFormat_)
		, useMipmap			(useMipmap_)
		, minFilter			(minFilter_)
		, magFilter			(magFilter_)
		, sWrap				(sWrap_)
		, tWrap				(tWrap_)
		, minValue			(minValue_)
		, maxValue			(maxValue_)
	{
	}
};

/*--------------------------------------------------------------------*//*!
 * \brief Struct for a shader program sources and related data
 *
 * A ProgramContext holds a program's vertex and fragment shader sources
 * as well as specifications of its attributes, uniforms, and textures.
 * When given to a StressCase, the string ${NS} is replaced by a magic
 * number that varies between different compilations of the same program;
 * the same replacement is done in attributes' and uniforms' names. This
 * can be used to avoid shader caching by the GL, by e.g. suffixing each
 * attribute, uniform and varying name with ${NS} in the shader source.
 *//*--------------------------------------------------------------------*/
struct ProgramContext
{
	std::string							vertexSource;
	std::string							fragmentSource;
	std::vector<VarSpec>				attributes;
	std::vector<VarSpec>				uniforms;

	std::vector<TextureSpec>			textureSpecs;		//!< \note If multiple textures have same unit, one of them is picked randomly.

	std::string							positionAttrName;	//!< \note Position attribute may get a bit more careful handling than just complete random.

	ProgramContext (const char* const vtxShaderSource_,
					const char* const fragShaderSource_,
					const char* const positionAttrName_)
		: vertexSource		(vtxShaderSource_)
		, fragmentSource	(fragShaderSource_)
		, positionAttrName	(positionAttrName_)
	{
	}
};

class LongStressCase : public tcu::TestCase
{
public:
	//! Probabilities for actions that may be taken on each iteration. \note The texture and buffer specific actions are randomized per texture or buffer.
	struct FeatureProbabilities
	{
		float rebuildProgram;				//!< Rebuild program, with variable name-mangling.
		float reuploadTexture;				//!< Reupload texture, even if it already exists and has been uploaded.
		float reuploadBuffer;				//!< Reupload buffer, even if it already exists and has been uploaded.
		float reuploadWithTexImage;			//!< Use glTexImage*() when re-uploading texture, not glTexSubImage*().
		float reuploadWithBufferData;		//!< Use glBufferData() when re-uploading buffer, not glBufferSubData().
		float deleteTexture;				//!< Delete texture at end of iteration, even if we could re-use it.
		float deleteBuffer;					//!< Delete buffer at end of iteration, even if we could re-use it.
		float wastefulTextureMemoryUsage;	//!< Don't re-use a texture, and don't delete it until given memory limit is hit.
		float wastefulBufferMemoryUsage;	//!< Don't re-use a buffer, and don't delete it until given memory limit is hit.
		float clientMemoryAttributeData;	//!< Use client memory for vertex attribute data when drawing (instead of GL buffers).
		float clientMemoryIndexData;		//!< Use client memory for vertex indices when drawing (instead of GL buffers).
		float randomBufferUploadTarget;		//!< Use a random target when setting buffer data (i.e. not necessarily the one it'll be ultimately bound to).
		float randomBufferUsage;			//!< Use a random buffer usage parameter with glBufferData(), instead of the ones specified as params for the case.
		float useDrawArrays;				//!< Use glDrawArrays() instead of glDrawElements().
		float separateAttributeBuffers;		//!< Give each vertex attribute its own buffer.

		// Named parameter idiom: helpers that can be used when making temporaries, e.g. FeatureProbabilities().pReuploadTexture(1.0f).pReuploadWithTexImage(1.0f)
		FeatureProbabilities& pRebuildProgram				(const float prob) { rebuildProgram					= prob; return *this; }
		FeatureProbabilities& pReuploadTexture				(const float prob) { reuploadTexture				= prob; return *this; }
		FeatureProbabilities& pReuploadBuffer				(const float prob) { reuploadBuffer					= prob; return *this; }
		FeatureProbabilities& pReuploadWithTexImage			(const float prob) { reuploadWithTexImage			= prob; return *this; }
		FeatureProbabilities& pReuploadWithBufferData		(const float prob) { reuploadWithBufferData			= prob; return *this; }
		FeatureProbabilities& pDeleteTexture				(const float prob) { deleteTexture					= prob; return *this; }
		FeatureProbabilities& pDeleteBuffer					(const float prob) { deleteBuffer					= prob; return *this; }
		FeatureProbabilities& pWastefulTextureMemoryUsage	(const float prob) { wastefulTextureMemoryUsage		= prob; return *this; }
		FeatureProbabilities& pWastefulBufferMemoryUsage	(const float prob) { wastefulBufferMemoryUsage		= prob; return *this; }
		FeatureProbabilities& pClientMemoryAttributeData	(const float prob) { clientMemoryAttributeData		= prob; return *this; }
		FeatureProbabilities& pClientMemoryIndexData		(const float prob) { clientMemoryIndexData			= prob; return *this; }
		FeatureProbabilities& pRandomBufferUploadTarget		(const float prob) { randomBufferUploadTarget		= prob; return *this; }
		FeatureProbabilities& pRandomBufferUsage			(const float prob) { randomBufferUsage				= prob; return *this; }
		FeatureProbabilities& pUseDrawArrays				(const float prob) { useDrawArrays					= prob; return *this; }
		FeatureProbabilities& pSeparateAttribBuffers		(const float prob) { separateAttributeBuffers		= prob; return *this; }

		FeatureProbabilities (void)
			: rebuildProgram				(0.0f)
			, reuploadTexture				(0.0f)
			, reuploadBuffer				(0.0f)
			, reuploadWithTexImage			(0.0f)
			, reuploadWithBufferData		(0.0f)
			, deleteTexture					(0.0f)
			, deleteBuffer					(0.0f)
			, wastefulTextureMemoryUsage	(0.0f)
			, wastefulBufferMemoryUsage		(0.0f)
			, clientMemoryAttributeData		(0.0f)
			, clientMemoryIndexData			(0.0f)
			, randomBufferUploadTarget		(0.0f)
			, randomBufferUsage				(0.0f)
			, useDrawArrays					(0.0f)
			, separateAttributeBuffers		(0.0f)
		{
		}
	};

															LongStressCase						(tcu::TestContext&						testCtx,
																								 const glu::RenderContext&				renderCtx,
																								 const char*							name,
																								 const char*							desc,
																								 int									maxTexMemoryUsageBytes, //!< Approximate upper bound on GL texture memory usage.
																								 int									maxBufMemoryUsageBytes, //!< Approximate upper bound on GL buffer memory usage.
																								 int									numDrawCallsPerIteration,
																								 int									numTrianglesPerDrawCall,
																								 const std::vector<ProgramContext>&		programContexts,
																								 const FeatureProbabilities&			probabilities,
																								 deUint32								indexBufferUsage,
																								 deUint32								attrBufferUsage,
																								 int									redundantBufferFactor = 1,
																								 bool									showDebugInfo = false);

															~LongStressCase						(void);

	void													init								(void);
	void													deinit								(void);

	IterateResult											iterate								(void);

private:
															LongStressCase						(const LongStressCase&);
	LongStressCase&											operator=							(const LongStressCase&);

	const glu::RenderContext&								m_renderCtx;
	const int												m_maxTexMemoryUsageBytes;
	const int												m_maxBufMemoryUsageBytes;
	const int												m_numDrawCallsPerIteration;
	const int												m_numTrianglesPerDrawCall;
	const int												m_numVerticesPerDrawCall;
	const std::vector<ProgramContext>						m_programContexts;
	const FeatureProbabilities								m_probabilities;
	const deUint32											m_indexBufferUsage;
	const deUint32											m_attrBufferUsage;
	const int												m_redundantBufferFactor; //!< By what factor we allocate redundant buffers. Default is 1, i.e. no redundancy.
	const bool												m_showDebugInfo;

	const int												m_numIterations;
	const bool												m_isGLES3;

	int														m_currentIteration;
	deUint64												m_startTimeSeconds; //!< Set at beginning of first iteration.
	deUint64												m_lastLogTime;
	int														m_lastLogIteration;
	int														m_currentLogEntryNdx;

	de::Random												m_rnd;
	LongStressCaseInternal::GLObjectManager<
		LongStressCaseInternal::Program>*					m_programs;
	LongStressCaseInternal::GLObjectManager<
		LongStressCaseInternal::Buffer>*					m_buffers;
	LongStressCaseInternal::GLObjectManager<
		LongStressCaseInternal::Texture>*					m_textures;
	std::vector<deUint16>									m_vertexIndices;

	struct ProgramResources
	{
		std::vector<deUint8>							attrDataBuf;
		std::vector<int>								attrDataOffsets;
		std::vector<int>								attrDataSizes;
		std::vector<de::SharedPtr<tcu::TextureLevel> >	unusedTextures;
		std::string										shaderNameManglingSuffix;
	};

	std::vector<ProgramResources>							m_programResources;

	LongStressCaseInternal::DebugInfoRenderer*				m_debugInfoRenderer;
};


} // gls
} // deqp

#endif // _GLSLONGSTRESSCASE_HPP
