/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2016 Google Inc.
 * Copyright (c) 2016 The Khronos Group Inc.
 *
 * 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 GLSL vector constructor tests.
 */ /*-------------------------------------------------------------------*/
#include "glcGLSLVectorConstructorTests.hpp"

#include "gluDefs.hpp"
#include "gluTextureUtil.hpp"
#include "gluDrawUtil.hpp"
#include "gluShaderProgram.hpp"

#include "glwDefs.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"

#include "tcuTestLog.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"

#include <functional>
#include <map>
#include <vector>
#include <sstream>
#include <string>
#include <tuple>

namespace deqp
{

namespace
{
using std::string;

using std::map;
using std::vector;

using std::function;
using std::bind;
using namespace std::placeholders;

using std::ostringstream;

enum struct TestType
{
	VERTEX_SHADER_ERROR = 0,
	FRAGMENT_SHADER_ERROR,
	VERTEX_SHADER,
	FRAGMENT_SHADER
};

struct TestDefinition
{
	vector<string>			outputTypes;
	vector<vector<string>>	inputTypeLists;
	string					extraFields;
};

const TestDefinition					tests[]					=
{
	{
		{ "vec2", "vec3", "vec4" },								// vector<string>			outputTypes
		{														// vector<vector<string>>	inputTypeLists
			{ "mat2" },
			{ "mat2x3" },
			{ "mat2x4" },
			{ "mat3" },
			{ "mat3x2" },
			{ "mat3x4" },
			{ "mat4" },
			{ "mat4x2" },
			{ "mat4x3" },
			{ "float", "mat2" },
			{ "float", "mat2x3" },
			{ "float", "mat2x4" },
			{ "float", "mat3" },
			{ "float", "mat3x2" },
			{ "float", "mat3x4" },
			{ "float", "mat4" },
			{ "float", "mat4x2" },
			{ "float", "mat4x3" },
		},
		"const float errorBound = 1.0E-5;\n"					// deUint32					extraFields;
	},
	{
		{ "ivec2", "ivec3", "ivec4" },							// vector<string>			outputTypes
		{														// vector<vector<string>>	inputTypeLists
			{ "mat2" },
			{ "mat2x3" },
			{ "mat2x4" },
			{ "mat3" },
			{ "mat3x2" },
			{ "mat3x4" },
			{ "mat4" },
			{ "mat4x2" },
			{ "mat4x3" },
			{ "int", "mat2" },
			{ "int", "mat2x3" },
			{ "int", "mat2x4" },
			{ "int", "mat3" },
			{ "int", "mat3x2" },
			{ "int", "mat3x4" },
			{ "int", "mat4" },
			{ "int", "mat4x2" },
			{ "int", "mat4x3" },
		},
		""														// deUint32					extraFields;
	},
	{
		{ "bvec2", "bvec3", "bvec4" },							// vector<string>			outputTypes
		{														// vector<vector<string>>	inputTypeLists
			{ "mat2" },
			{ "mat2x3" },
			{ "mat2x4" },
			{ "mat3" },
			{ "mat3x2" },
			{ "mat3x4" },
			{ "mat4" },
			{ "mat4x2" },
			{ "mat4x3" },
			{ "bool", "mat2" },
			{ "bool", "mat2x3" },
			{ "bool", "mat2x4" },
			{ "bool", "mat3" },
			{ "bool", "mat3x2" },
			{ "bool", "mat3x4" },
			{ "bool", "mat4" },
			{ "bool", "mat4x2" },
			{ "bool", "mat4x3" },
		},
		""														// deUint32					extraFields;
	},
};

struct TestParams
{
	string			name;
	string			description;
	TestType		testType;
	string			outputType;
	vector<string>	inputTypes;
	string			extraFields;
};

vector<TestParams> generateTestParams()
{
	vector<TestParams> result;
	result.reserve(64);
	for(const auto& test : tests)
	{
		for(const auto& outputType : test.outputTypes)
		{
			for(const auto& inputTypes : test.inputTypeLists)
			{
				ostringstream testNameVs, testNameFs;
				ostringstream testDescriptionVs, testDescriptionFs;
				testNameVs << outputType << "_from";
				testNameFs << outputType << "_from";
				testDescriptionVs << outputType << "(";
				testDescriptionFs << outputType << "(";
				for(vector<string>::size_type i = 0; i < inputTypes.size(); ++i)
				{
					const auto& inputType = inputTypes[i];
					testNameVs << "_" << inputType;
					testNameFs << "_" << inputType;
					if (i > 0) {
						testDescriptionVs << ",";
						testDescriptionFs << ",";
					}
					testDescriptionVs << inputType;
				}
				ostringstream testNameInvalidVs, testNameInvalidFs;
				testNameInvalidVs << testNameVs.str() << "_" << inputTypes[0] << "_invalid_vs";
				testNameInvalidFs << testNameFs.str() << "_" << inputTypes[0] << "_invalid_fs";

				testNameVs << "_vs";
				testNameFs << "_fs";
				testDescriptionVs << ") vertex shader";
				testDescriptionFs << ") fragment shader";
				result.push_back({ testNameVs.str(), testDescriptionVs.str(), TestType::VERTEX_SHADER, outputType, inputTypes, test.extraFields });
				result.push_back({ testNameFs.str(), testDescriptionFs.str(), TestType::FRAGMENT_SHADER, outputType, inputTypes, test.extraFields });

				vector<string> failInputTypes;
				failInputTypes.insert(failInputTypes.end(), inputTypes.begin(), inputTypes.end());
				failInputTypes.push_back(inputTypes[0]);
				testDescriptionVs << " invalid";
				testDescriptionFs << " invalid";
				result.push_back({ testNameInvalidVs.str(), testDescriptionVs.str(), TestType::VERTEX_SHADER_ERROR, outputType, failInputTypes, test.extraFields });
				result.push_back({ testNameInvalidFs.str(), testDescriptionFs.str(), TestType::FRAGMENT_SHADER_ERROR, outputType, failInputTypes, test.extraFields });

			}
		}
	}
	return result;
}

const string									defaultVertexShader		=
	"${GLSL_VERSION}\n"
	"in vec4 vPosition;\n"
	"void main()\n"
	"{\n"
	"    gl_Position = vPosition;\n"
	"}\n";

const string									defaultFragmentShader	=
	"${GLSL_VERSION}\n"
	"precision mediump float;\n"
	"in vec4 vColor;\n"
	"out vec4 my_FragColor;\n"
	"void main() {\n"
	"    my_FragColor = vColor;\n"
	"}\n";

const string									vertexShaderTemplate	=
	"${GLSL_VERSION}\n"
	"in vec4 vPosition;\n"
	"precision mediump int;\n"
	"precision mediump float;\n"
	"const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
	"const vec4 red	  = vec4(1.0, 0.0, 0.0, 1.0);\n"
	"${TEST_CONSTANTS}"
	"out vec4 vColor;\n"
	"void main() {\n"
	"    ${TEST_CODE}\n"
	"    if ${TEST_CONDITION}\n"
	"        vColor = green;\n"
	"    else\n"
	"        vColor = red;\n"
	"    gl_Position = vPosition;\n"
	"}\n";

const string									fragmentShaderTemplate	=
	"${GLSL_VERSION}\n"
	"precision mediump int;\n"
	"precision mediump float;\n"
	"const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
	"const vec4 red	  = vec4(1.0, 0.0, 0.0, 1.0);\n"
	"${TEST_CONSTANTS}"
	"out vec4 my_FragColor;\n"
	"void main() {\n"
	"    ${TEST_CODE}\n"
	"    if ${TEST_CONDITION}\n"
	"        my_FragColor = green;\n"
	"    else\n"
	"        my_FragColor = red;\n"
	"}\n";

const map<string, string>						testConditions			=
{
	{ "vec2"	, "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound)" },
	{ "vec3"	, "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound && abs(v[2] - 2.0) <= errorBound)" },
	{ "vec4"	, "(abs(v[0] - 0.0) <= errorBound && abs(v[1] - 1.0) <= errorBound && abs(v[2] - 2.0) <= errorBound && abs(v[3] - 3.0) <= errorBound)" },
	{ "ivec2"	, "(v[0] == 0 && v[1] == 1)" },
	{ "ivec3"	, "(v[0] == 0 && v[1] == 1 && v[2] == 2)" },
	{ "ivec4"	, "(v[0] == 0 && v[1] == 1 && v[2] == 2 && v[3] == 3)" },
	{ "bvec2"	, "(v[0] == false && v[1] == true)" },
	{ "bvec3"	, "(v[0] == false && v[1] == true && v[2] == true)" },
	{ "bvec4"	, "(v[0] == false && v[1] == true && v[2] == true && v[3] == true)" }
};

typedef function<void (ostringstream&, size_t)> GeneratorFn;

struct DataTypeInfo
{
	size_t			numElements;
	GeneratorFn		valueFn;
	GeneratorFn		beforeValueFn;
	GeneratorFn		afterValueFn;
};

void generateValueFloat(ostringstream& out, const size_t index)
{
	out << index << ".0";
}

void generateValueInt(ostringstream& out, const size_t index)
{
	out << index;
}

void generateValueBool(ostringstream& out, const size_t index)
{
	out << ((index != 0) ? "true" : "false");
}

void generateCtorOpen(const char* className, ostringstream& out, const size_t)
{
	out << className << "(";
}

void generateCtorClose(ostringstream &out, const size_t)
{
	out << ")";
}

const map<string, DataTypeInfo>					dataTypeInfos			=
{
	//				numElements	, valueFn			, beforeValueFn								, afterValueFn
	{ "float"	, { 1			, generateValueFloat, DE_NULL									, DE_NULL			} },
	{ "vec2"	, { 2			, generateValueFloat, bind(generateCtorOpen, "vec2", _1, _2)	, generateCtorClose	} },
	{ "vec3"	, { 3			, generateValueFloat, bind(generateCtorOpen, "vec3", _1, _2)	, generateCtorClose	} },
	{ "vec4"	, { 4			, generateValueFloat, bind(generateCtorOpen, "vec4", _1, _2)	, generateCtorClose	} },
	{ "int"		, { 1			, generateValueInt	, DE_NULL									, DE_NULL			} },
	{ "ivec2"	, { 2			, generateValueInt	, bind(generateCtorOpen, "ivec2", _1, _2)	, generateCtorClose	} },
	{ "ivec3"	, { 3			, generateValueInt	, bind(generateCtorOpen, "ivec3", _1, _2)	, generateCtorClose	} },
	{ "ivec4"	, { 4			, generateValueInt	, bind(generateCtorOpen, "ivec4", _1, _2)	, generateCtorClose	} },
	{ "bool"	, { 1			, generateValueBool	, DE_NULL									, DE_NULL			} },
	{ "bvec2"	, { 2			, generateValueBool	, bind(generateCtorOpen, "bvec2", _1, _2)	, generateCtorClose	} },
	{ "bvec3"	, { 3			, generateValueBool	, bind(generateCtorOpen, "bvec3", _1, _2)	, generateCtorClose	} },
	{ "bvec4"	, { 4			, generateValueBool	, bind(generateCtorOpen, "bvec4", _1, _2)	, generateCtorClose	} },
	{ "mat2"	, { 4			, generateValueFloat, bind(generateCtorOpen, "mat2", _1, _2)	, generateCtorClose	} },
	{ "mat2x3"	, { 6			, generateValueFloat, bind(generateCtorOpen, "mat2x3", _1, _2)	, generateCtorClose	} },
	{ "mat2x4"	, { 8			, generateValueFloat, bind(generateCtorOpen, "mat2x4", _1, _2)	, generateCtorClose	} },
	{ "mat3"	, { 9			, generateValueFloat, bind(generateCtorOpen, "mat3", _1, _2)	, generateCtorClose	} },
	{ "mat3x2"	, { 6			, generateValueFloat, bind(generateCtorOpen, "mat3x2", _1, _2)	, generateCtorClose	} },
	{ "mat3x4"	, { 12			, generateValueFloat, bind(generateCtorOpen, "mat3x4", _1, _2)	, generateCtorClose	} },
	{ "mat4"	, { 16			, generateValueFloat, bind(generateCtorOpen, "mat4", _1, _2)	, generateCtorClose	} },
	{ "mat4x2"	, { 8			, generateValueFloat, bind(generateCtorOpen, "mat4x2", _1, _2)	, generateCtorClose	} },
	{ "mat4x3"	, { 12			, generateValueFloat, bind(generateCtorOpen, "mat4x3", _1, _2)	, generateCtorClose	} },
};

string generateTestCode(const string& outputType, const vector<string>& inputTypes)
{
	ostringstream output;
	const auto outputTypeInfo = dataTypeInfos.find(outputType);
	DE_ASSERT(outputTypeInfo != dataTypeInfos.end());

	output << outputType << " v = ";
	if (outputTypeInfo->second.beforeValueFn != DE_NULL)
		outputTypeInfo->second.beforeValueFn(output, -1);
	int outputElementsRemaining = outputTypeInfo->second.numElements;
	int outputElementIndex = 0;
	for(size_t i = 0; i < inputTypes.size() && outputElementsRemaining > 0; ++i)
	{
		const auto& inputType = inputTypes[i];
		const auto inputTypeInfo = dataTypeInfos.find(inputType);
		DE_ASSERT(inputTypeInfo != dataTypeInfos.end());

		if (outputElementIndex > 0)
			output << ", ";
		if (inputTypeInfo->second.beforeValueFn != DE_NULL)
			inputTypeInfo->second.beforeValueFn(output, i);
		for(size_t j = 0; j < inputTypeInfo->second.numElements; ++j)
		{
			if (j > 0)
				output << ", ";

			inputTypeInfo->second.valueFn(output, outputElementIndex++);
			--outputElementsRemaining;
		}
		if (inputTypeInfo->second.afterValueFn != DE_NULL)
			inputTypeInfo->second.afterValueFn(output, i);
	}
	if (outputTypeInfo->second.afterValueFn != DE_NULL)
		outputTypeInfo->second.afterValueFn(output, -1);
	output << ";";
	return output.str();
}

string replacePlaceholders(const string& shaderTemplate, const TestParams& params, const glu::GLSLVersion glslVersion)
{
	const auto condition = testConditions.find(params.outputType);
	return tcu::StringTemplate(shaderTemplate).specialize(
	{
		{ "GLSL_VERSION"	, glu::getGLSLVersionDeclaration(glslVersion) },
		{ "TEST_CONSTANTS"	, params.extraFields },
		{ "TEST_CODE"		, generateTestCode(params.outputType, params.inputTypes) },
		{ "TEST_CONDITION"	, (condition != testConditions.end()) ? condition->second : "" }
	});
}

const vector<float>								positions				=
{
	-1.0f, -1.0f,
	 1.0f, -1.0f,
	-1.0f,	1.0f,
	 1.0f,	1.0f
};

const vector<deUint32>							indices					= { 0, 1, 2, 3 };

const int										RENDERTARGET_WIDTH		= 16;
const int										RENDERTARGET_HEIGHT		= 16;

class GLSLVectorConstructorTestCase : public deqp::TestCase
{
public:
	GLSLVectorConstructorTestCase(deqp::Context& context, glu::GLSLVersion glslVersion, const TestParams& params);

	void init(void);
	void deinit(void);
	IterateResult iterate();

private:
	void setupRenderTarget();
	void releaseRenderTarget();

	const glu::GLSLVersion		m_glslVersion;
	const TestParams			m_params;
	glw::GLuint					m_fboId;
	glw::GLuint					m_rboId;

	string						m_vertexShader;
	string						m_fragmentShader;
};

GLSLVectorConstructorTestCase::GLSLVectorConstructorTestCase(deqp::Context& context, glu::GLSLVersion glslVersion, const TestParams& params)
	: TestCase(context, params.name.c_str(), params.description.c_str())
	, m_glslVersion(glslVersion)
	, m_params(params)
	, m_fboId(0)
	, m_rboId(0)
{
	switch(m_params.testType)
	{
	case TestType::VERTEX_SHADER_ERROR:
	case TestType::VERTEX_SHADER:
		m_vertexShader = replacePlaceholders(vertexShaderTemplate, m_params, m_glslVersion);
		m_fragmentShader = replacePlaceholders(defaultFragmentShader, m_params, m_glslVersion);
		break;
	case TestType::FRAGMENT_SHADER_ERROR:
	case TestType::FRAGMENT_SHADER:
		m_vertexShader = replacePlaceholders(defaultVertexShader, m_params, m_glslVersion);
		m_fragmentShader = replacePlaceholders(fragmentShaderTemplate, m_params, m_glslVersion);
		break;
	}
}

void GLSLVectorConstructorTestCase::init(void)
{
	deqp::TestCase::init();
}

void GLSLVectorConstructorTestCase::deinit(void)
{
	deqp::TestCase::deinit();
}

GLSLVectorConstructorTestCase::IterateResult GLSLVectorConstructorTestCase::iterate()
{
	const auto&								renderContext	= m_context.getRenderContext();
	const auto&								gl				= renderContext.getFunctions();
	const auto								textureFormat	= tcu::TextureFormat(tcu::TextureFormat::RGBA,	tcu::TextureFormat::UNORM_INT8);
	const auto								transferFormat	= glu::getTransferFormat(textureFormat);

	setupRenderTarget();

	glu::ShaderProgram program(renderContext, glu::makeVtxFragSources(m_vertexShader, m_fragmentShader));
	if (!program.isOk())
	{
		switch(m_params.testType)
		{
		case TestType::VERTEX_SHADER_ERROR:
		case TestType::FRAGMENT_SHADER_ERROR:
			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
			return STOP;
		default:
			TCU_FAIL("Shader compilation failed:\nVertex shader:\n" + m_vertexShader + "\nFragment shader:\n" + m_fragmentShader);
		}
	}

	const vector<glu::VertexArrayBinding>	vertexArrays	=
	{
		glu::va::Float("vPosition", 2, positions.size() / 2, 0, positions.data()),
	};

	gl.useProgram(program.getProgram());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram failed");

	gl.clear(GL_COLOR_BUFFER_BIT);

	glu::draw(renderContext, program.getProgram(),
			  static_cast<int>(vertexArrays.size()), vertexArrays.data(),
			  glu::pr::TriangleStrip(static_cast<int>(indices.size()), indices.data()));

	const auto								pixelSize		= tcu::getPixelSize(textureFormat);
	vector<deUint8>							fbData			(RENDERTARGET_WIDTH * RENDERTARGET_HEIGHT * pixelSize);

	if (pixelSize < 4)
		gl.pixelStorei(GL_PACK_ALIGNMENT, 1);

	gl.readPixels(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, transferFormat.format, transferFormat.dataType, fbData.data());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");

	tcu::ConstPixelBufferAccess				fbAccess		{ textureFormat, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT, 1, fbData.data() };
	const auto								expectedColor	= tcu::RGBA::green().toVec();
	bool pass = true;
	for(int y = 0; pass && y < RENDERTARGET_HEIGHT; ++y)
		for(int x = 0; x < RENDERTARGET_WIDTH; ++x)
			if (fbAccess.getPixel(x,y) != expectedColor)
			{
				pass = false;
				break;
			}

	releaseRenderTarget();

	const qpTestResult						result			= (pass ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL);
	const char*								desc			= (pass ? "Pass" : "Pixel mismatch; vector initialization failed");

	m_testCtx.setTestResult(result, desc);

	return STOP;
}

void GLSLVectorConstructorTestCase::setupRenderTarget()
{
	const auto&		renderContext	= m_context.getRenderContext();
	const auto&		gl				= renderContext.getFunctions();

	gl.genFramebuffers(1, &m_fboId);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenFramebuffers");

	gl.genRenderbuffers(1, &m_rboId);
	GLU_EXPECT_NO_ERROR(gl.getError(), "GenRenderBuffers");

	gl.bindRenderbuffer(GL_RENDERBUFFER, m_rboId);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindRenderBuffer");

	gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "RenderBufferStorage");

	gl.bindFramebuffer(GL_FRAMEBUFFER, m_fboId);
	GLU_EXPECT_NO_ERROR(gl.getError(), "BindFrameBuffer");

	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_rboId);
	GLU_EXPECT_NO_ERROR(gl.getError(), "FrameBufferRenderBuffer");

	glw::GLenum		drawBuffer		= GL_COLOR_ATTACHMENT0;
	gl.drawBuffers(1, &drawBuffer);
	GLU_EXPECT_NO_ERROR(gl.getError(), "DrawBuffers");

	glw::GLfloat	clearColor[4]	= { 0, 0, 0, 0 };
	gl.clearBufferfv(GL_COLOR, 0, clearColor);
	GLU_EXPECT_NO_ERROR(gl.getError(), "ClearBuffers");

	gl.viewport(0, 0, RENDERTARGET_WIDTH, RENDERTARGET_HEIGHT);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Viewport");
}

void GLSLVectorConstructorTestCase::releaseRenderTarget()
{
	const auto&	renderContext	= m_context.getRenderContext();
	const auto&	gl				= renderContext.getFunctions();
	if (m_fboId != 0)
	{
		gl.deleteFramebuffers(1, &m_fboId);
		m_fboId = 0;
	}
	if (m_rboId != 0)
	{
		gl.deleteRenderbuffers(1, &m_rboId);
		m_rboId = 0;
	}
}

}

GLSLVectorConstructorTests::GLSLVectorConstructorTests(Context& context, glu::GLSLVersion glslVersion)
	: deqp::TestCaseGroup(context, "glsl_constructors", "GLSL vector constructor tests")
	, m_glslVersion(glslVersion)
{
}

GLSLVectorConstructorTests::~GLSLVectorConstructorTests()
{
}

void GLSLVectorConstructorTests::init()
{
	for(const auto& params : generateTestParams())
		addChild(new GLSLVectorConstructorTestCase(m_context, m_glslVersion, params));
}

} // deqp
