/*-------------------------------------------------------------------------
 * 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 CTS runner.
 */ /*-------------------------------------------------------------------*/

#include "glcTestRunner.hpp"
#include "deFilePath.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"
#include "glcConfigList.hpp"
#include "qpXmlWriter.h"
#include "tcuApp.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTestLog.hpp"
#include "tcuTestSessionExecutor.hpp"

#include <iterator>

namespace glcts
{

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

// RunSession

class RunSession
{
public:
	RunSession(tcu::Platform& platform, tcu::Archive& archive, const int numArgs, const char* const* args)
		: m_cmdLine(numArgs, args)
		, m_log(m_cmdLine.getLogFileName(), m_cmdLine.getLogFlags())
		, m_app(platform, archive, m_log, m_cmdLine)
	{
		const std::string sessionInfo = "#sessionInfo commandLineParameters \"";
		m_log.writeSessionInfo(sessionInfo + m_cmdLine.getInitialCmdLine() + "\"\n");
	}

	inline bool iterate(void)
	{
		return m_app.iterate();
	}

	inline const tcu::TestRunStatus& getResult(void) const
	{
		return m_app.getResult();
	}

private:
	tcu::CommandLine m_cmdLine;
	tcu::TestLog	 m_log;
	tcu::App		 m_app;
};

static void appendConfigArgs(const Config& config, std::vector<std::string>& args, const char* fboConfig)
{
	if (fboConfig != NULL)
	{
		args.push_back(string("--deqp-gl-config-name=") + fboConfig);
		args.push_back("--deqp-surface-type=fbo");
	}

	if (config.type != CONFIGTYPE_DEFAULT)
	{
		// \todo [2013-05-06 pyry] Test all surface types for some configs?
		if (fboConfig == NULL)
		{
			if (config.surfaceTypes & SURFACETYPE_WINDOW)
				args.push_back("--deqp-surface-type=window");
			else if (config.surfaceTypes & SURFACETYPE_PBUFFER)
				args.push_back("--deqp-surface-type=pbuffer");
			else if (config.surfaceTypes & SURFACETYPE_PIXMAP)
				args.push_back("--deqp-surface-type=pixmap");
		}

		args.push_back(string("--deqp-gl-config-id=") + de::toString(config.id));

		if (config.type == CONFIGTYPE_EGL)
			args.push_back("--deqp-gl-context-type=egl");
		else if (config.type == CONFIGTYPE_WGL)
			args.push_back("--deqp-gl-context-type=wgl");
	}
}

typedef struct configInfo
{
	deInt32 redBits;
	deInt32 greenBits;
	deInt32 blueBits;
	deInt32 alphaBits;
	deInt32 depthBits;
	deInt32 stencilBits;
	deInt32 samples;
} configInfo;

static configInfo parseConfigBitsFromName(const char* configName)
{
	configInfo cfgInfo;
	static const struct
	{
		const char* name;
		int			redBits;
		int			greenBits;
		int			blueBits;
		int			alphaBits;
	} colorCfgs[] = {
		{ "rgba8888", 8, 8, 8, 8 }, { "rgb565", 5, 6, 5, 0 },
	};
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorCfgs); ndx++)
	{
		if (!strncmp(configName, colorCfgs[ndx].name, strlen(colorCfgs[ndx].name)))
		{
			cfgInfo.redBits   = colorCfgs[ndx].redBits;
			cfgInfo.greenBits = colorCfgs[ndx].greenBits;
			cfgInfo.blueBits  = colorCfgs[ndx].blueBits;
			cfgInfo.alphaBits = colorCfgs[ndx].alphaBits;

			configName += strlen(colorCfgs[ndx].name);
			break;
		}
	}

	static const struct
	{
		const char* name;
		int			depthBits;
	} depthCfgs[] = {
		{ "d0", 0 }, { "d24", 24 },
	};
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthCfgs); ndx++)
	{
		if (!strncmp(configName, depthCfgs[ndx].name, strlen(depthCfgs[ndx].name)))
		{
			cfgInfo.depthBits = depthCfgs[ndx].depthBits;

			configName += strlen(depthCfgs[ndx].name);
			break;
		}
	}

	static const struct
	{
		const char* name;
		int			stencilBits;
	} stencilCfgs[] = {
		{ "s0", 0 }, { "s8", 8 },
	};
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(stencilCfgs); ndx++)
	{
		if (!strncmp(configName, stencilCfgs[ndx].name, strlen(stencilCfgs[ndx].name)))
		{
			cfgInfo.stencilBits = stencilCfgs[ndx].stencilBits;

			configName += strlen(stencilCfgs[ndx].name);
			break;
		}
	}

	static const struct
	{
		const char* name;
		int			samples;
	} multiSampleCfgs[] = {
		{ "ms0", 0 }, { "ms4", 4 },
	};
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(multiSampleCfgs); ndx++)
	{
		if (!strncmp(configName, multiSampleCfgs[ndx].name, strlen(multiSampleCfgs[ndx].name)))
		{
			cfgInfo.samples = multiSampleCfgs[ndx].samples;

			configName += strlen(multiSampleCfgs[ndx].name);
			break;
		}
	}

	return cfgInfo;
}

static const char* getApiName(glu::ApiType apiType)
{
	if (apiType == glu::ApiType::es(2, 0))
		return "gles2";
	else if (apiType == glu::ApiType::es(3, 0))
		return "gles3";
	else if (apiType == glu::ApiType::es(3, 1))
		return "gles31";
	else if (apiType == glu::ApiType::es(3, 2))
		return "gles32";
	else if (apiType == glu::ApiType::core(3, 0))
		return "gl30";
	else if (apiType == glu::ApiType::core(3, 1))
		return "gl31";
	else if (apiType == glu::ApiType::core(3, 2))
		return "gl32";
	else if (apiType == glu::ApiType::core(3, 3))
		return "gl33";
	else if (apiType == glu::ApiType::core(4, 0))
		return "gl40";
	else if (apiType == glu::ApiType::core(4, 1))
		return "gl41";
	else if (apiType == glu::ApiType::core(4, 2))
		return "gl42";
	else if (apiType == glu::ApiType::core(4, 3))
		return "gl43";
	else if (apiType == glu::ApiType::core(4, 4))
		return "gl44";
	else if (apiType == glu::ApiType::core(4, 5))
		return "gl45";
	else if (apiType == glu::ApiType::core(4, 6))
		return "gl46";
	else
		throw std::runtime_error("Unknown context type");
}

static const string getCaseListFileOption(const char* mustpassDir, const char* apiName, const char* mustpassName)
{
#if DE_OS == DE_OS_ANDROID
	const string case_list_option = "--deqp-caselist-resource=";
#else
	const string case_list_option = "--deqp-caselist-file=";
#endif
	return case_list_option + mustpassDir + apiName + "-" + mustpassName + ".txt";
}

static const string getLogFileName(const char* apiName, const char* configName, const int iterId, const int runId,
								   const int width, const int height, const int seed)
{
	string res = string("config-") + apiName + "-" + configName + "-cfg-" + de::toString(iterId) + "-run-" +
				 de::toString(runId) + "-width-" + de::toString(width) + "-height-" + de::toString(height);
	if (seed != -1)
	{
		res += "-seed-" + de::toString(seed);
	}
	res += ".qpa";

	return res;
}

static void getBaseOptions(std::vector<std::string>& args, const char* mustpassDir, const char* apiName,
						   const char* configName, const char* screenRotation, int width, int height)
{
	args.push_back(getCaseListFileOption(mustpassDir, apiName, configName));
	args.push_back(string("--deqp-screen-rotation=") + screenRotation);
	args.push_back(string("--deqp-surface-width=") + de::toString(width));
	args.push_back(string("--deqp-surface-height=") + de::toString(height));
	args.push_back("--deqp-watchdog=disable");
}

static bool isGLConfigCompatible(configInfo cfgInfo, const AOSPConfig& config)
{
	return cfgInfo.redBits == config.redBits && cfgInfo.greenBits == config.greenBits &&
		   cfgInfo.blueBits == config.blueBits && cfgInfo.alphaBits == config.alphaBits &&
		   cfgInfo.depthBits == config.depthBits && cfgInfo.stencilBits == config.stencilBits &&
		   cfgInfo.samples == config.samples;
}

static void getTestRunsForAOSPEGL(vector<TestRunParams>& runs, const ConfigList& configs)
{
#include "glcAospMustpassEgl.hpp"

	for (int i = 0; i < DE_LENGTH_OF_ARRAY(aosp_mustpass_egl_first_cfg); ++i)
	{
		configInfo cfgInfo = parseConfigBitsFromName(aosp_mustpass_egl_first_cfg[i].glConfigName);

		vector<AOSPConfig>::const_iterator cfgIter;
		for (cfgIter = configs.aospConfigs.begin(); cfgIter != configs.aospConfigs.end(); ++cfgIter)
		{
			// find first compatible config
			if ((*cfgIter).type == CONFIGTYPE_EGL && isGLConfigCompatible(cfgInfo, *cfgIter))
			{
				break;
			}
		}

		if (cfgIter == configs.aospConfigs.end())
		{
			// No suitable configuration found. Skipping EGL tests
			continue;
		}

		const char* apiName = "egl";

		const int width   = aosp_mustpass_egl_first_cfg[i].surfaceWidth;
		const int height  = aosp_mustpass_egl_first_cfg[i].surfaceHeight;

		TestRunParams params;
		params.logFilename =
			getLogFileName(apiName, aosp_mustpass_egl_first_cfg[i].configName, 1, i, width, height, -1);
		getBaseOptions(params.args, mustpassDir, apiName, aosp_mustpass_egl_first_cfg[i].configName,
					   aosp_mustpass_egl_first_cfg[i].screenRotation, width, height);

		params.args.push_back(string("--deqp-gl-config-name=") + string(aosp_mustpass_egl_first_cfg[i].glConfigName));

		runs.push_back(params);
	}
}

static void getTestRunsForAOSPES(vector<TestRunParams>& runs, const ConfigList& configs, const glu::ApiType apiType)
{
#include "glcAospMustpassEs.hpp"

	for (int i = 0; i < DE_LENGTH_OF_ARRAY(aosp_mustpass_es_first_cfg); ++i)
	{
		if (!glu::contextSupports(glu::ContextType(apiType), aosp_mustpass_es_first_cfg[i].apiType))
			continue;

		configInfo cfgInfo = parseConfigBitsFromName(aosp_mustpass_es_first_cfg[i].glConfigName);

		vector<AOSPConfig>::const_iterator cfgIter;
		for (cfgIter = configs.aospConfigs.begin(); cfgIter != configs.aospConfigs.end(); ++cfgIter)
		{
			// find first compatible config
			if (isGLConfigCompatible(cfgInfo, *cfgIter))
			{
				break;
			}
		}

		if (cfgIter == configs.aospConfigs.end())
		{
			TCU_FAIL(("No suitable configuration found for GL config " +
					  de::toString(aosp_mustpass_es_first_cfg[i].glConfigName))
						 .c_str());
			return;
		}

		const char* apiName = getApiName(aosp_mustpass_es_first_cfg[i].apiType);

		const int width   = aosp_mustpass_es_first_cfg[i].surfaceWidth;
		const int height  = aosp_mustpass_es_first_cfg[i].surfaceHeight;

		TestRunParams params;
		params.logFilename = getLogFileName(apiName, aosp_mustpass_es_first_cfg[i].configName, 1, i, width, height, -1);
		getBaseOptions(params.args, mustpassDir, apiName, aosp_mustpass_es_first_cfg[i].configName,
					   aosp_mustpass_es_first_cfg[i].screenRotation, width, height);

		params.args.push_back(string("--deqp-gl-config-name=") + string(aosp_mustpass_es_first_cfg[i].glConfigName));

		//set surface type
		if ((*cfgIter).surfaceTypes & SURFACETYPE_WINDOW)
			params.args.push_back("--deqp-surface-type=window");
		else if ((*cfgIter).surfaceTypes & SURFACETYPE_PBUFFER)
			params.args.push_back("--deqp-surface-type=pbuffer");
		else if ((*cfgIter).surfaceTypes & SURFACETYPE_PIXMAP)
			params.args.push_back("--deqp-surface-type=pixmap");
		runs.push_back(params);
	}
}

static void getTestRunsForNoContext(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs, const RunParams* runParams,
									const int numRunParams, const char* mustpassDir)
{
	vector<Config>::const_iterator cfgIter = configs.configs.begin();

	for (int i = 0; i < numRunParams; ++i)
	{
		if (!glu::contextSupports(glu::ContextType(type), runParams[i].apiType))
				continue;

		const char* apiName = getApiName(runParams[i].apiType);

		const int width  = runParams[i].surfaceWidth;
		const int height = runParams[i].surfaceHeight;
		const int seed   = runParams[i].baseSeed;

		TestRunParams params;
		params.logFilename = getLogFileName(apiName, runParams[i].configName, 1, i, width, height, seed);

		getBaseOptions(params.args, mustpassDir, apiName, runParams[i].configName, runParams[i].screenRotation, width,
					   height);

		params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));

		appendConfigArgs(*cfgIter, params.args, runParams[i].fboConfig);

		runs.push_back(params);
	}
}

static void getTestRunsForNoContextES(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
{
#include "glcKhronosMustpassEsNocontext.hpp"
	getTestRunsForNoContext(type, runs, configs, khronos_mustpass_es_nocontext_first_cfg,
							DE_LENGTH_OF_ARRAY(khronos_mustpass_es_nocontext_first_cfg), mustpassDir);
}

static void getTestRunsForSingleConfig(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs, const RunParams* runParams,
									const int numRunParams, const char* mustpassDir)
{
	vector<Config>::const_iterator cfgIter = configs.configs.begin();

	for (int i = 0; i < numRunParams; ++i)
	{
		if (type != runParams[i].apiType)
			continue;

		const char* apiName = getApiName(runParams[i].apiType);

		const int width  = runParams[i].surfaceWidth;
		const int height = runParams[i].surfaceHeight;
		const int seed   = runParams[i].baseSeed;

		TestRunParams params;
		params.logFilename = getLogFileName(apiName, runParams[i].configName, 1, i, width, height, seed);

		getBaseOptions(params.args, mustpassDir, apiName, runParams[i].configName, runParams[i].screenRotation, width,
					   height);

		params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));

		appendConfigArgs(*cfgIter, params.args, runParams[i].fboConfig);

		runs.push_back(params);
	}
}
static void getTestRunsForSingleConfigES(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
{
#include "glcKhronosMustpassEsSingleConfig.hpp"
	getTestRunsForSingleConfig(type, runs, configs, khronos_mustpass_es_single_config_first_cfg,
							   DE_LENGTH_OF_ARRAY(khronos_mustpass_es_single_config_first_cfg), mustpassDir);
}

static void getTestRunsForES(glu::ApiType type, const ConfigList& configs, vector<TestRunParams>& runs)
{
	getTestRunsForAOSPEGL(runs, configs);
	getTestRunsForAOSPES(runs, configs, type);
	getTestRunsForNoContextES(type, runs, configs);
	getTestRunsForSingleConfigES(type, runs, configs);

#include "glcKhronosMustpassEs.hpp"

	for (vector<Config>::const_iterator cfgIter = configs.configs.begin(); cfgIter != configs.configs.end(); ++cfgIter)
	{
		const bool isFirst		= cfgIter == configs.configs.begin();
		const int  numRunParams = isFirst ? DE_LENGTH_OF_ARRAY(khronos_mustpass_es_first_cfg) :
										   DE_LENGTH_OF_ARRAY(khronos_mustpass_es_other_cfg);
		const RunParams* runParams = isFirst ? khronos_mustpass_es_first_cfg : khronos_mustpass_es_other_cfg;

		for (int runNdx = 0; runNdx < numRunParams; runNdx++)
		{
			if (!glu::contextSupports(glu::ContextType(type), runParams[runNdx].apiType))
				continue;

			const char* apiName = getApiName(runParams[runNdx].apiType);

			const int width   = runParams[runNdx].surfaceWidth;
			const int height  = runParams[runNdx].surfaceHeight;
			const int seed	= runParams[runNdx].baseSeed;

			TestRunParams params;

			params.logFilename =
				getLogFileName(apiName, runParams[runNdx].configName, cfgIter->id, runNdx, width, height, seed);

			getBaseOptions(params.args, mustpassDir, apiName, runParams[runNdx].configName,
						   runParams[runNdx].screenRotation, width, height);
			params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));

			appendConfigArgs(*cfgIter, params.args, runParams[runNdx].fboConfig);

			runs.push_back(params);
		}
	}
}

static void getTestRunsForNoContextGL(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
{
#include "glcKhronosMustpassGlNocontext.hpp"
	getTestRunsForNoContext(type, runs, configs, khronos_mustpass_gl_nocontext_first_cfg,
							DE_LENGTH_OF_ARRAY(khronos_mustpass_gl_nocontext_first_cfg), mustpassDir);
}
static void getTestRunsForSingleConfigGL(glu::ApiType type, vector<TestRunParams>& runs, const ConfigList& configs)
{
#include "glcKhronosMustpassGlSingleConfig.hpp"
	getTestRunsForSingleConfig(type, runs, configs, khronos_mustpass_gl_single_config_first_cfg,
							   DE_LENGTH_OF_ARRAY(khronos_mustpass_gl_single_config_first_cfg), mustpassDir);
}

static void getTestRunsForGL(glu::ApiType type, const ConfigList& configs, vector<TestRunParams>& runs)
{
	getTestRunsForNoContextGL(type, runs, configs);
	getTestRunsForSingleConfigGL(type, runs, configs);
#include "glcKhronosMustpassGl.hpp"

	for (vector<Config>::const_iterator cfgIter = configs.configs.begin(); cfgIter != configs.configs.end(); ++cfgIter)
	{
		const bool isFirst		= cfgIter == configs.configs.begin();
		const int  numRunParams = isFirst ? DE_LENGTH_OF_ARRAY(khronos_mustpass_gl_first_cfg) :
										   DE_LENGTH_OF_ARRAY(khronos_mustpass_gl_other_cfg);
		const RunParams* runParams = isFirst ? khronos_mustpass_gl_first_cfg : khronos_mustpass_gl_other_cfg;

		for (int runNdx = 0; runNdx < numRunParams; runNdx++)
		{
			if (type != runParams[runNdx].apiType)
				continue;

			const char* apiName = getApiName(runParams[runNdx].apiType);

			const int width   = runParams[runNdx].surfaceWidth;
			const int height  = runParams[runNdx].surfaceHeight;
			const int seed	= runParams[runNdx].baseSeed;

			TestRunParams params;

			params.logFilename =
				getLogFileName(apiName, runParams[runNdx].configName, cfgIter->id, runNdx, width, height, seed);

			getBaseOptions(params.args, mustpassDir, apiName, runParams[runNdx].configName,
						   runParams[runNdx].screenRotation, width, height);
			params.args.push_back(string("--deqp-base-seed=") + de::toString(seed));

			appendConfigArgs(*cfgIter, params.args, runParams[runNdx].fboConfig);

			runs.push_back(params);
		}
	}
}

static void getTestRunParams(glu::ApiType type, const ConfigList& configs, vector<TestRunParams>& runs)
{
	switch (type.getProfile())
	{
	case glu::PROFILE_CORE:
		getTestRunsForGL(type, configs, runs);
		break;
	case glu::PROFILE_ES:
		getTestRunsForES(type, configs, runs);
		break;
	default:
		throw std::runtime_error("Unknown context type");
	}
}

struct FileDeleter
{
	void operator()(FILE* file) const
	{
		if (file)
			fclose(file);
	}
};

struct XmlWriterDeleter
{
	void operator()(qpXmlWriter* writer) const
	{
		if (writer)
			qpXmlWriter_destroy(writer);
	}
};

static const char* getRunTypeName(glu::ApiType type)
{
	if (type == glu::ApiType::es(2, 0))
		return "es2";
	else if (type == glu::ApiType::es(3, 0))
		return "es3";
	else if (type == glu::ApiType::es(3, 1))
		return "es31";
	else if (type == glu::ApiType::es(3, 2))
		return "es32";
	else if (type == glu::ApiType::core(3, 0))
		return "gl30";
	else if (type == glu::ApiType::core(3, 1))
		return "gl31";
	else if (type == glu::ApiType::core(3, 2))
		return "gl32";
	else if (type == glu::ApiType::core(3, 3))
		return "gl33";
	else if (type == glu::ApiType::core(4, 0))
		return "gl40";
	else if (type == glu::ApiType::core(4, 1))
		return "gl41";
	else if (type == glu::ApiType::core(4, 2))
		return "gl42";
	else if (type == glu::ApiType::core(4, 3))
		return "gl43";
	else if (type == glu::ApiType::core(4, 4))
		return "gl44";
	else if (type == glu::ApiType::core(4, 5))
		return "gl45";
	else if (type == glu::ApiType::core(4, 6))
		return "gl46";
	else
		return DE_NULL;
}

#define XML_CHECK(X) \
	if (!(X))        \
	throw tcu::Exception("Writing XML failed")

static void writeRunSummary(const TestRunSummary& summary, const char* filename)
{
	de::UniquePtr<FILE, FileDeleter> out(fopen(filename, "wb"));
	if (!out)
		throw tcu::Exception(string("Failed to open ") + filename);

	de::UniquePtr<qpXmlWriter, XmlWriterDeleter> writer(qpXmlWriter_createFileWriter(out.get(), DE_FALSE, DE_FALSE));
	if (!writer)
		throw std::bad_alloc();

	XML_CHECK(qpXmlWriter_startDocument(writer.get()));

	{
		qpXmlAttribute attribs[2];

		attribs[0] = qpSetStringAttrib("Type", getRunTypeName(summary.runType));
		attribs[1] = qpSetBoolAttrib("Conformant", summary.isConformant ? DE_TRUE : DE_FALSE);

		XML_CHECK(qpXmlWriter_startElement(writer.get(), "Summary", DE_LENGTH_OF_ARRAY(attribs), attribs));
	}

	// Config run
	{
		qpXmlAttribute attribs[1];
		attribs[0] = qpSetStringAttrib("FileName", summary.configLogFilename.c_str());
		XML_CHECK(qpXmlWriter_startElement(writer.get(), "Configs", DE_LENGTH_OF_ARRAY(attribs), attribs) &&
				  qpXmlWriter_endElement(writer.get(), "Configs"));
	}

	// Record test run parameters (log filename & command line).
	for (vector<TestRunParams>::const_iterator runIter = summary.runParams.begin(); runIter != summary.runParams.end();
		 ++runIter)
	{
		string		   cmdLine;
		qpXmlAttribute attribs[2];

		for (vector<string>::const_iterator argIter = runIter->args.begin(); argIter != runIter->args.end(); ++argIter)
		{
			if (argIter != runIter->args.begin())
				cmdLine += " ";
			cmdLine += *argIter;
		}

		attribs[0] = qpSetStringAttrib("FileName", runIter->logFilename.c_str());
		attribs[1] = qpSetStringAttrib("CmdLine", cmdLine.c_str());

		XML_CHECK(qpXmlWriter_startElement(writer.get(), "TestRun", DE_LENGTH_OF_ARRAY(attribs), attribs) &&
				  qpXmlWriter_endElement(writer.get(), "TestRun"));
	}

	XML_CHECK(qpXmlWriter_endElement(writer.get(), "Summary"));
	XML_CHECK(qpXmlWriter_endDocument(writer.get()));
}

#undef XML_CHECK

TestRunner::TestRunner(tcu::Platform& platform, tcu::Archive& archive, const char* logDirPath, glu::ApiType type,
					   deUint32 flags)
	: m_platform(platform)
	, m_archive(archive)
	, m_logDirPath(logDirPath)
	, m_type(type)
	, m_flags(flags)
	, m_iterState(ITERATE_INIT)
	, m_curSession(DE_NULL)
	, m_sessionsExecuted(0)
	, m_sessionsPassed(0)
	, m_sessionsFailed(0)
{
}

TestRunner::~TestRunner(void)
{
	delete m_curSession;
}

bool TestRunner::iterate(void)
{
	switch (m_iterState)
	{
	case ITERATE_INIT:
		init();
		m_iterState = (m_sessionIter != m_runSessions.end()) ? ITERATE_INIT_SESSION : ITERATE_DEINIT;
		return true;

	case ITERATE_DEINIT:
		deinit();
		m_iterState = ITERATE_INIT;
		return false;

	case ITERATE_INIT_SESSION:
		DE_ASSERT(m_sessionIter != m_runSessions.end());
		initSession(*m_sessionIter);
		if (m_flags & PRINT_SUMMARY)
			m_iterState = ITERATE_DEINIT_SESSION;
		else
			m_iterState = ITERATE_ITERATE_SESSION;
		return true;

	case ITERATE_DEINIT_SESSION:
		deinitSession();
		++m_sessionIter;
		m_iterState = (m_sessionIter != m_runSessions.end()) ? ITERATE_INIT_SESSION : ITERATE_DEINIT;
		return true;

	case ITERATE_ITERATE_SESSION:
		if (!iterateSession())
			m_iterState = ITERATE_DEINIT_SESSION;
		return true;

	default:
		DE_ASSERT(false);
		return false;
	}
}

void TestRunner::init(void)
{
	DE_ASSERT(m_runSessions.empty() && m_summary.runParams.empty());

	tcu::print("Running %s conformance\n", glu::getApiTypeDescription(m_type));

	m_summary.runType = m_type;

	// Get list of configs to test.
	ConfigList configList;
	getDefaultConfigList(m_platform, m_type, configList);

	tcu::print("  found %d compatible and %d excluded configs\n", (int)configList.configs.size(),
			   (int)configList.excludedConfigs.size());

	// Config list run.
	{
		const char*   configLogFilename = "configs.qpa";
		TestRunParams configRun;

		configRun.logFilename = configLogFilename;
		configRun.args.push_back("--deqp-case=CTS-Configs.*");
		m_runSessions.push_back(configRun);

		m_summary.configLogFilename = configLogFilename;
	}

	// Conformance test type specific runs
	getTestRunParams(m_type, configList, m_runSessions);

	// Record run params for summary.
	for (std::vector<TestRunParams>::const_iterator runIter = m_runSessions.begin() + 1; runIter != m_runSessions.end();
		 ++runIter)
		m_summary.runParams.push_back(*runIter);

	// Session iterator
	m_sessionIter = m_runSessions.begin();
}

void TestRunner::deinit(void)
{
	// Print out totals.
	bool isConformant_ = m_sessionsExecuted == m_sessionsPassed;
	DE_ASSERT(m_sessionsExecuted == m_sessionsPassed + m_sessionsFailed);
	tcu::print("\n%d/%d sessions passed, conformance test %s\n", m_sessionsPassed, m_sessionsExecuted,
			   isConformant_ ? "PASSED" : "FAILED");

	m_summary.isConformant = isConformant_;

	// Write out summary.
	writeRunSummary(m_summary, de::FilePath::join(m_logDirPath, "cts-run-summary.xml").getPath());

	m_runSessions.clear();
	m_summary.clear();
}

void TestRunner::initSession(const TestRunParams& runParams)
{
	DE_ASSERT(!m_curSession);

	tcu::print("\n  Test run %d / %d\n", (int)(m_sessionIter - m_runSessions.begin() + 1), (int)m_runSessions.size());

	// Compute final args for run.
	vector<string> args(runParams.args);
	args.push_back(string("--deqp-log-filename=") + de::FilePath::join(m_logDirPath, runParams.logFilename).getPath());

	if (!(m_flags & VERBOSE_IMAGES))
		args.push_back("--deqp-log-images=disable");

	if (!(m_flags & VERBOSE_SHADERS))
		args.push_back("--deqp-log-shader-sources=disable");

	std::ostringstream			  ostr;
	std::ostream_iterator<string> out_it(ostr, ", ");
	std::copy(args.begin(), args.end(), out_it);
	tcu::print("\n  Config: %s \n\n", ostr.str().c_str());

	// Translate to argc, argv
	vector<const char*> argv;
	argv.push_back("cts-runner"); // Dummy binary name
	for (vector<string>::const_iterator i = args.begin(); i != args.end(); i++)
		argv.push_back(i->c_str());

	// Create session
	m_curSession = new RunSession(m_platform, m_archive, (int)argv.size(), &argv[0]);
}

void TestRunner::deinitSession(void)
{
	DE_ASSERT(m_curSession);

	// Collect results.
	// \note NotSupported is treated as pass.
	const tcu::TestRunStatus& result = m_curSession->getResult();
	bool					  isOk =
		result.numExecuted == (result.numPassed + result.numNotSupported + result.numWarnings) && result.isComplete;

	DE_ASSERT(result.numExecuted == result.numPassed + result.numFailed + result.numNotSupported + result.numWarnings);

	m_sessionsExecuted += 1;
	(isOk ? m_sessionsPassed : m_sessionsFailed) += 1;

	delete m_curSession;
	m_curSession = DE_NULL;
}

inline bool TestRunner::iterateSession(void)
{
	return m_curSession->iterate();
}

} // glcts
