/*-------------------------------------------------------------------------
 * OpenGL Conformance Test Suite
 * -----------------------------
 *
 * Copyright (c) 2020 Google Inc.
 * Copyright (c) 2020 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  es3cNumberParsingTests.cpp
 * \brief Tests for numeric value parsing in GLSL ES 3.0
 */ /*-------------------------------------------------------------------*/

#include "es3cNumberParsingTests.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 <string>
#include <vector>
#include <map>

#include <functional>

namespace es3cts
{

namespace
{
using std::string;
using std::vector;
using std::map;

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

static const string					defaultVertexShader					=
	"#version 300 es\n"
	"in vec4 vPosition;\n"
	"void main()\n"
	"{\n"
	"    gl_Position = vPosition;\n"
	"}\n";

static const string					fragmentShaderTemplate				=
	"#version 300 es\n"
	"precision highp float;\n"
	"out vec4 my_FragColor;\n"
	"${TEST_GLOBALS}"
	"void main()\n"
	"{\n"
    "${TEST_CODE}"
    "    my_FragColor = vec4(0.0, correct, 0.0, 1.0);\n"
	"}\n";

typedef function<void (const glu::ShaderProgram&, const glw::Functions&)> SetupUniformsFn;

enum struct TestType
{
	NORMAL				= 0,
	EXPECT_SHADER_FAIL
};

struct TestParams
{
	TestType			testType;
	string				name;
	string				description;
	string				testGlobals;
	string				testCode;
	SetupUniformsFn	setupUniformsFn;
};

static void initializeExpectedValue(const glu::ShaderProgram& program, const glw::Functions& gl, const deUint32 value);
static void initializeZeroValue(const glu::ShaderProgram& program, const glw::Functions& gl);

static const TestParams			tests[]									=
{
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_above_signed_range_decimal",																	// string			name
		"Test that uint value higher than INT_MAX is parsed correctly",													// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 3221225472u;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 3221225472u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_above_signed_range_base8",																	// string			name
		"Test that uint value higher than INT_MAX is parsed correctly in base 8 (octal)",								// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 030000000000u;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 3221225472u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_above_signed_range_base16",																	// string			name
		"Test that uint value higher than INT_MAX is parsed correctly in base 16 (hex)",								// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 0xc0000000u;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 3221225472u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_smallest_value_above_signed_range_decimal",													// string			name
		"Test that uint value equal to INT_MAX+1 is parsed correctly",													// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 2147483648u;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 2147483648u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_smallest_value_above_signed_range_base8",														// string			name
		"Test that uint value equal to INT_MAX+1 is parsed correctly in base 8 (octal)",								// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 020000000000u;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 2147483648u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_smallest_value_above_signed_range_base16",													// string			name
		"Test that uint value equal to INT_MAX+1 is parsed correctly in base 16 (hex)",									// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 0x80000000u;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 2147483648u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_max_value_decimal",																			// string			name
		"Test that uint value equal to UINT_MAX is parsed correctly",													// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 4294967295u;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 4294967295u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_max_value_base8",																				// string			name
		"Test that uint value equal to UINT_MAX is parsed correctly in base 8 (octal)",									// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 037777777777u;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 4294967295u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_max_value_base16",																			// string			name
		"Test that uint value equal to UINT_MAX is parsed correctly in base 16 (hex)",									// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = 0xffffffffu;\n"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 4294967295u)																// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::EXPECT_SHADER_FAIL,																					// TestType			testType
		"unsigned_integer_too_large_value_invalid",																		// string			name
		"Test that uint value outside uint range fails to compile",														// string			description
		"",																												// string			testGlobals
		"    uint i        = 0xfffffffffu;"
		"    float correct = 0.0;",
		nullptr																											// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"unsigned_integer_negative_value_as_uint",																		// string			name
		"Test that -1u is parsed correctly",																			// string			description
		"uniform uint expected;\n",																						// string			testGlobals
		"    uint i        = -1u;"
		"    float correct = (i == expected) ? 1.0 : 0.0;\n",
		bind(initializeExpectedValue, _1, _2, 0xffffffffu)																// SetupUniformsFn	setupUniformsFn
	},
	/* The following floating point parsing tests are taken from the Khronos WebGL conformance tests at:
	 *     https://www.khronos.org/registry/webgl/sdk/tests/conformance2/glsl3/float-parsing.html */
	{
		TestType::NORMAL,																								// TestType			testType
		"float_out_of_range_as_infinity",																				// string			name
		"Floats of too large magnitude should be converted infinity",													// string			description
		"",																												// string			testGlobals
		"    // Out-of-range floats should overflow to infinity\n"														// string			testCode
		"    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"
		"    // \"If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity\"\n"
		"    float correct = isinf(1.0e40) ? 1.0 : 0.0;\n",
		nullptr																											// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"float_out_of_range_as_zero",																					// string			name
		"Floats of too small magnitude should be converted to zero",													// string			description
		"",																												// string			testGlobals
		"    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"																	// string			testCode
		"    // \"A value with a magnitude too small to be represented as a mantissa and exponent is converted to zero.\"\n"
		"    // 1.0e-50 is small enough that it can't even be stored as subnormal.\n"
		"    float correct = (1.0e-50 == 0.0) ? 1.0 : 0.0;\n",
		nullptr																											// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"float_no_limit_on_number_of_digits_positive_exponent",															// string			name
		"Number of digits in any digit-sequence is not limited - test with a small mantissa and large exponent",		// string			description
		"",																												// string			testGlobals
		"    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"																	// string			testCode
		"    // \"There is no limit on the number of digits in any digit-sequence.\"\n"
		"    // The below float string has 100 zeros after the decimal point, but represents 1.0.\n"
		"    float x = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e101;\n"
		"    float correct = (x == 1.0) ? 1.0 : 0.0;\n",
		nullptr																											// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"float_no_limit_on_number_of_digits_negative_exponent",															// string			name
		"Number of digits in any digit-sequence is not limited - test with a large mantissa and negative exponent",		// string			description
		"",																												// string			testGlobals
		"    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"																	// string			testCode
		"    // \"There is no limit on the number of digits in any digit-sequence.\"\n"
		"    // The below float string has 100 zeros, but represents 1.0.\n"
		"    float x = 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0e-100;\n"
		"    float correct = (x == 1.0) ? 1.0 : 0.0;\n",
		nullptr																											// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"float_slightly_out_of_range_exponent_as_positive_infinity",													// string			name
		"Test that an exponent that slightly overflows signed 32-bit int range works",									// string			description
		"",																												// string			testGlobals
		"    // Out-of-range floats should overflow to infinity\n"														// string			testCode
		"    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"
		"    // \"If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity\"\n"
		"    float correct = isinf(1.0e2147483649) ? 1.0 : 0.0;\n",
		nullptr																											// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"float_overflow_to_positive_infinity",																			// string			name
		"Out-of-range floats greater than zero should overflow to positive infinity",									// string			description
		"uniform float zero;\n",																						// string			testGlobals
		"    // Out-of-range floats should overflow to infinity\n"														// string			testCode
		"    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"
		"    // \"If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity\"\n"
		"    float f = 1.0e2048 - zero;\n"
		"    float correct = (isinf(f) && f > 0.0) ? 1.0 : 0.0;\n",
		initializeZeroValue																								// SetupUniformsFn	setupUniformsFn
	},
	{
		TestType::NORMAL,																								// TestType			testType
		"float_overflow_to_negative_infinity",																			// string			name
		"Out-of-range floats less than zero should overflow to negative infinity",										// string			description
		"uniform float zero;\n",																						// string			testGlobals
		"    // Out-of-range floats should overflow to infinity\n"														// string			testCode
		"    // GLSL ES 3.00.6 section 4.1.4 Floats:\n"
		"    // \"If the value of the floating point number is too large (small) to be stored as a single precision value, it is converted to positive (negative) infinity\"\n"
		"    float f = -1.0e2048 + zero;\n"
		"    float correct = (isinf(f) && f < 0.0) ? 1.0 : 0.0;\n",
		initializeZeroValue																								// SetupUniformsFn	setupUniformsFn
	}
};

static void initializeExpectedValue(const glu::ShaderProgram& program, const glw::Functions& gl, const deUint32 value)
{
	const auto location = gl.getUniformLocation(program.getProgram(), "expected");
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation call failed");

	gl.uniform1ui(location, value);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Set uniform value failed");
}

static void initializeZeroValue(const glu::ShaderProgram& program, const glw::Functions& gl)
{
	const auto location = gl.getUniformLocation(program.getProgram(), "zero");
	GLU_EXPECT_NO_ERROR(gl.getError(), "GetAttribLocation call failed");

	gl.uniform1f(location, 0.0f);
	GLU_EXPECT_NO_ERROR(gl.getError(), "Set uniform value failed");
}

static string replacePlaceholders(const string& shaderTemplate, const TestParams& params)
{
	map<string,string> fields;
	fields["TEST_GLOBALS"]	= params.testGlobals;
	fields["TEST_CODE"]		= params.testCode;

	tcu::StringTemplate output(shaderTemplate);
	return output.specialize(fields);
}

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

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

const deInt32						RENDERTARGET_WIDTH		= 16;
const deInt32						RENDERTARGET_HEIGHT		= 16;

class NumberParsingCase : public deqp::TestCase
{
public:
	NumberParsingCase(deqp::Context& context, const string& name, const TestParams& params, const string& vertexShader, const string& fragmentShader);

	IterateResult iterate();

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

	glw::GLuint			m_fboId;
	glw::GLuint			m_rboId;

	const TestParams&	m_params;
	string				m_vertexShader;
	string				m_fragmentShader;
};

NumberParsingCase::NumberParsingCase(deqp::Context& context, const string& name, const TestParams& params, const string& vertexShader, const string& fragmentShader)
	: TestCase(context, name.c_str(), params.description.c_str())
	, m_fboId(0)
	, m_rboId(0)
	, m_params(params)
	, m_vertexShader(vertexShader)
	, m_fragmentShader(fragmentShader)
{
}

NumberParsingCase::IterateResult NumberParsingCase::iterate(void)
{
	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::EXPECT_SHADER_FAIL:
			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);
			break;
		}

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

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

	if (m_params.setupUniformsFn != DE_NULL)
		m_params.setupUniformsFn(program, gl);

	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);
	std::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; numeric value parsed incorrectly");

	m_testCtx.setTestResult(result, desc);

	return STOP;
}

void NumberParsingCase::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 NumberParsingCase::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;
	}
}

}

NumberParsingTests::NumberParsingTests(deqp::Context& context)
	: deqp::TestCaseGroup(context, "number_parsing", "GLSL number parsing tests")
{
}

NumberParsingTests::~NumberParsingTests(void)
{
}

void NumberParsingTests::init(void)
{
	for(const auto& params : tests)
	{
		addChild(new NumberParsingCase(m_context, params.name, params, defaultVertexShader, replacePlaceholders(fragmentShaderTemplate, params)));
	}
}

}
