/*-------------------------------------------------------------------------
 * drawElements Quality Program Random Shader Generator
 * ----------------------------------------------------
 *
 * 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 Shader generator.
 *//*--------------------------------------------------------------------*/

#include "rsgShaderGenerator.hpp"
#include "rsgFunctionGenerator.hpp"
#include "rsgToken.hpp"
#include "rsgPrettyPrinter.hpp"
#include "rsgUtils.hpp"
#include "deString.h"

#include <iterator>

using std::string;
using std::vector;

namespace rsg
{

ShaderGenerator::ShaderGenerator (GeneratorState& state)
	: m_state		(state)
	, m_varManager	(state.getNameAllocator())
{
	state.setVariableManager(m_varManager);
}

ShaderGenerator::~ShaderGenerator (void)
{
}

namespace
{

const char* getFragColorName (const GeneratorState& state)
{
	switch (state.getProgramParameters().version)
	{
		case VERSION_100:	return "gl_FragColor";
		case VERSION_300:	return "dEQP_FragColor";
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

void createAssignment (BlockStatement& block, const Variable* dstVar, const Variable* srcVar)
{
	VariableRead* varRead = new VariableRead(srcVar);
	try
	{
		block.addChild(new AssignStatement( dstVar, varRead));
	}
	catch (const std::exception&)
	{
		delete varRead;
		throw;
	}
}

const ValueEntry* findByName (VariableManager& varManager, const char* name)
{
	AnyEntry::Iterator	iter	= varManager.getBegin<AnyEntry>();
	AnyEntry::Iterator	end		= varManager.getEnd<AnyEntry>();
	for (; iter != end; iter++)
	{
		const ValueEntry* entry = *iter;
		if (deStringEqual(entry->getVariable()->getName(), name))
			return entry;
	}
	return DE_NULL;
}

void genVertexPassthrough (GeneratorState& state, Shader& shader)
{
	// Create copies from shader inputs to outputs
	vector<const ValueEntry*> entries;
	std::copy(state.getVariableManager().getBegin<AnyEntry>(), state.getVariableManager().getEnd<AnyEntry>(), std::inserter(entries, entries.begin()));

	for (vector<const ValueEntry*>::const_iterator i = entries.begin(); i != entries.end(); i++)
	{
		const ValueEntry*	entry		= *i;
		const Variable*		outVar		= entry->getVariable();
		std::string			inVarName;

		if (outVar->getStorage() != Variable::STORAGE_SHADER_OUT)
			continue;

		// Name: a_[name], remove v_ -prefix if such exists
		inVarName = "a_";
		if (deStringBeginsWith(outVar->getName(), "v_"))
			inVarName += (outVar->getName()+2);
		else
			inVarName += outVar->getName();

		Variable* inVar = state.getVariableManager().allocate(outVar->getType(), Variable::STORAGE_SHADER_IN, inVarName.c_str());

		// Update value range. This will be stored into shader input info.
		state.getVariableManager().setValue(inVar, entry->getValueRange());

		// Add assignment from input to output into main() body
		createAssignment(shader.getMain().getBody(), entry->getVariable(), inVar);
	}
}

void genFragmentPassthrough (GeneratorState& state, Shader& shader)
{
	// Add simple gl_FragColor = v_color; assignment
	const ValueEntry* fragColorEntry = findByName(state.getVariableManager(), getFragColorName(state));
	TCU_CHECK(fragColorEntry);

	Variable* inColorVariable = state.getVariableManager().allocate(fragColorEntry->getVariable()->getType(), Variable::STORAGE_SHADER_IN, "v_color");

	state.getVariableManager().setValue(inColorVariable, fragColorEntry->getValueRange());
	createAssignment(shader.getMain().getBody(), fragColorEntry->getVariable(), inColorVariable);
}

// Sets undefined (-inf..inf) components to some meaningful values. Used for sanitizing final shader input value ranges.
void fillUndefinedComponents (ValueRangeAccess valueRange)
{
	VariableType::Type baseType = valueRange.getType().getBaseType();
	TCU_CHECK(baseType == VariableType::TYPE_FLOAT	||
			  baseType == VariableType::TYPE_INT	||
			  baseType == VariableType::TYPE_BOOL);

	for (int elemNdx = 0; elemNdx < valueRange.getType().getNumElements(); elemNdx++)
	{
		if (isUndefinedValueRange(valueRange.component(elemNdx)))
		{
			ValueAccess min = valueRange.component(elemNdx).getMin();
			ValueAccess max = valueRange.component(elemNdx).getMax();

			switch (baseType)
			{
				case VariableType::TYPE_FLOAT:	min = 0.0f;		max = 1.0f;		break;
				case VariableType::TYPE_INT:	min = 0;		max = 1;		break;
				case VariableType::TYPE_BOOL:	min = false;	max = true;		break;
				default: DE_ASSERT(DE_FALSE);
			}
		}
	}
}

void fillUndefinedShaderInputs (vector<ShaderInput*>& inputs)
{
	for (vector<ShaderInput*>::iterator i = inputs.begin(); i != inputs.end(); i++)
	{
		if (!(*i)->getVariable()->getType().isSampler()) // Samplers are assigned at program-level.
			fillUndefinedComponents((*i)->getValueRange());
	}
}

} // anonymous

void ShaderGenerator::generate (const ShaderParameters& shaderParams, Shader& shader, const vector<ShaderInput*>& outputs)
{
	// Global scopes
	VariableScope&	globalVariableScope	= shader.getGlobalScope();
	ValueScope		globalValueScope;

	// Init state
	m_state.setShader(shaderParams, shader);
	DE_ASSERT(m_state.getExpressionFlags() == 0);

	// Reserve some scalars for gl_Position & dEQP_Position
	ReservedScalars reservedScalars;
	if (shader.getType() == Shader::TYPE_VERTEX)
		m_state.getVariableManager().reserve(reservedScalars, 4*2);

	// Push global scopes
	m_varManager.pushVariableScope(globalVariableScope);
	m_varManager.pushValueScope(globalValueScope);

	// Init shader outputs.
	{
		for (vector<ShaderInput*>::const_iterator i = outputs.begin(); i != outputs.end(); i++)
		{
			const ShaderInput*	input		= *i;
			Variable*			variable	= m_state.getVariableManager().allocate(input->getVariable()->getType(), Variable::STORAGE_SHADER_OUT, input->getVariable()->getName());

			m_state.getVariableManager().setValue(variable, input->getValueRange());
		}

		if (shader.getType() == Shader::TYPE_FRAGMENT)
		{
			// gl_FragColor
			// \todo [2011-11-22 pyry] Multiple outputs from fragment shader!
			Variable*	fragColorVar	= m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_OUT, getFragColorName(m_state));
			ValueRange	valueRange(fragColorVar->getType());

			valueRange.getMin() = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f);
			valueRange.getMax() = tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f);

			fragColorVar->setLayoutLocation(0); // Bind color output to location 0 (applies to GLSL ES 3.0 onwards).

			m_state.getVariableManager().setValue(fragColorVar, valueRange);
		}
	}

	// Construct shader code.
	{
		Function& main = shader.getMain();
		main.setReturnType(VariableType(VariableType::TYPE_VOID));

		if (shaderParams.randomize)
		{
			FunctionGenerator funcGen(m_state, main);

			// Mandate assignment into to all shader outputs in main()
			const vector<Variable*>& liveVars = globalVariableScope.getLiveVariables();
			for (vector<Variable*>::const_iterator i = liveVars.begin(); i != liveVars.end(); i++)
			{
				Variable* variable = *i;
				if (variable->getStorage() == Variable::STORAGE_SHADER_OUT)
					funcGen.requireAssignment(variable);
			}

			funcGen.generate();
		}
		else
		{
			if (shader.getType() == Shader::TYPE_VERTEX)
				genVertexPassthrough(m_state, shader);
			else
			{
				DE_ASSERT(shader.getType() == Shader::TYPE_FRAGMENT);
				genFragmentPassthrough(m_state, shader);
			}
		}

		if (shader.getType() == Shader::TYPE_VERTEX)
		{
			// Add gl_Position = dEQP_Position;
			m_state.getVariableManager().release(reservedScalars);

			Variable* glPosVariable = m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_OUT, "gl_Position");
			Variable* qpPosVariable = m_state.getVariableManager().allocate(VariableType(VariableType::TYPE_FLOAT, 4), Variable::STORAGE_SHADER_IN, "dEQP_Position");

			ValueRange valueRange(glPosVariable->getType());

			valueRange.getMin() = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f);
			valueRange.getMax() = tcu::Vec4( 1.0f,  1.0f, 0.0f, 1.0f);

			m_state.getVariableManager().setValue(qpPosVariable, valueRange); // \todo [2011-05-24 pyry] No expression should be able to use gl_Position or dEQP_Position..

			createAssignment(main.getBody(), glPosVariable, qpPosVariable);
		}
	}

	// Declare live global variables.
	{
		vector<Variable*> liveVariables;
		std::copy(globalVariableScope.getLiveVariables().begin(), globalVariableScope.getLiveVariables().end(), std::inserter(liveVariables, liveVariables.begin()));

		vector<Variable*> createDeclarationStatementVars;

		for (vector<Variable*>::iterator i = liveVariables.begin(); i != liveVariables.end(); i++)
		{
			Variable*		variable	= *i;
			const char*		name		= variable->getName();
			bool			declare		= !deStringBeginsWith(name, "gl_"); // Do not declare built-in types.

			// Create input entries (store value range) if necessary
			vector<ShaderInput*>& inputs	= shader.getInputs();
			vector<ShaderInput*>& uniforms	= shader.getUniforms();

			switch (variable->getStorage())
			{
				case Variable::STORAGE_SHADER_IN:
				{
					const ValueEntry* value = m_state.getVariableManager().getValue(variable);

					inputs.reserve(inputs.size()+1);
					inputs.push_back(new ShaderInput(variable, value->getValueRange()));
					break;
				}

				case Variable::STORAGE_UNIFORM:
				{
					const ValueEntry* value = m_state.getVariableManager().getValue(variable);

					uniforms.reserve(uniforms.size()+1);
					uniforms.push_back(new ShaderInput(variable, value->getValueRange()));
					break;
				}

				default:
					break;
			}

			if (declare)
				createDeclarationStatementVars.push_back(variable);
			else
			{
				// Just move to global scope without declaration statement.
				m_state.getVariableManager().declareVariable(variable);
			}
		}

		// All global initializers must be constant expressions, no variable allocation is allowed
		DE_ASSERT(m_state.getExpressionFlags() == 0);
		m_state.pushExpressionFlags(CONST_EXPR|NO_VAR_ALLOCATION);

		// Create declaration statements
		for (vector<Variable*>::iterator i = createDeclarationStatementVars.begin(); i != createDeclarationStatementVars.end(); i++)
		{
			shader.getGlobalStatements().reserve(shader.getGlobalStatements().size());
			shader.getGlobalStatements().push_back(new DeclarationStatement(m_state, *i));
		}

		m_state.popExpressionFlags();
	}

	// Pop global scopes
	m_varManager.popVariableScope();
	m_varManager.popValueScope();

	// Fill undefined (unused) components in inputs with dummy values
	fillUndefinedShaderInputs(shader.getInputs());
	fillUndefinedShaderInputs(shader.getUniforms());

	// Tokenize shader and write source
	{
		TokenStream tokenStr;
		shader.tokenize(m_state, tokenStr);

		std::ostringstream	str;
		PrettyPrinter		printer(str);

		// Append #version if necessary.
		if (m_state.getProgramParameters().version == VERSION_300)
			str << "#version 300 es\n";

		printer.append(tokenStr);
		shader.setSource(str.str().c_str());
	}
}

} // rsg
