/*-------------------------------------------------------------------------
 * drawElements Quality Program Test Executor
 * ------------------------------------------
 *
 * 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 Test case result parser.
 *//*--------------------------------------------------------------------*/

#include "xeTestResultParser.hpp"
#include "xeTestCaseResult.hpp"
#include "xeBatchResult.hpp"
#include "deString.h"
#include "deInt32.h"

#include <sstream>
#include <stdlib.h>

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

namespace xe
{

static inline int toInt (const char* str)
{
	return atoi(str);
}

static inline double toDouble (const char* str)
{
	return atof(str);
}

static inline deInt64 toInt64 (const char* str)
{
	std::istringstream	s	(str);
	deInt64				val;

	s >> val;

	return val;
}

static inline bool toBool (const char* str)
{
	return deStringEqual(str, "OK") || deStringEqual(str, "True");
}

static const char* stripLeadingWhitespace (const char* str)
{
	int whitespaceCount = 0;

	while (str[whitespaceCount]	!= 0	&&
		   (str[whitespaceCount] == ' '		||
			str[whitespaceCount] == '\t'	||
			str[whitespaceCount] == '\r'	||
			str[whitespaceCount] == '\n'))
		whitespaceCount += 1;

	return str + whitespaceCount;
}

struct EnumMapEntry
{
	deUint32		hash;
	const char*		name;
	int				value;
};

static const EnumMapEntry s_statusCodeMap[] =
{
	{ 0x7c8a99bc,	"Pass",					TESTSTATUSCODE_PASS						},
	{ 0x7c851ca1,	"Fail",					TESTSTATUSCODE_FAIL						},
	{ 0x10ecd324,	"QualityWarning",		TESTSTATUSCODE_QUALITY_WARNING			},
	{ 0x341ae835,	"CompatibilityWarning",	TESTSTATUSCODE_COMPATIBILITY_WARNING	},
	{ 0x058acbca,	"Pending",				TESTSTATUSCODE_PENDING					},
	{ 0xc4d74b26,	"Running",				TESTSTATUSCODE_RUNNING					},
	{ 0x6409f93c,	"NotSupported",			TESTSTATUSCODE_NOT_SUPPORTED			},
	{ 0xfa5a9ab7,	"ResourceError",		TESTSTATUSCODE_RESOURCE_ERROR			},
	{ 0xad6793ec,	"InternalError",		TESTSTATUSCODE_INTERNAL_ERROR			},
	{ 0x838f3034,	"Canceled",				TESTSTATUSCODE_CANCELED					},
	{ 0x42b6efac,	"Timeout",				TESTSTATUSCODE_TIMEOUT					},
	{ 0x0cfb98f6,	"Crash",				TESTSTATUSCODE_CRASH					},
	{ 0xe326e01d,	"Disabled",				TESTSTATUSCODE_DISABLED					},
	{ 0x77061af2,	"Terminated",			TESTSTATUSCODE_TERMINATED				}
};

static const EnumMapEntry s_resultItemMap[] =
{
	{ 0xce8ac2e4,	"Result",				ri::TYPE_RESULT			},
	{ 0x7c8cdcea,	"Text",					ri::TYPE_TEXT			},
	{ 0xc6540c6e,	"Number",				ri::TYPE_NUMBER			},
	{ 0x0d656c88,	"Image",				ri::TYPE_IMAGE			},
	{ 0x8ac9ee14,	"ImageSet",				ri::TYPE_IMAGESET		},
	{ 0x1181fa5a,	"VertexShader",			ri::TYPE_SHADER			},
	{ 0xa93daef0,	"FragmentShader",		ri::TYPE_SHADER			},
	{ 0x8f066128,	"GeometryShader",		ri::TYPE_SHADER			},
	{ 0x235a931c,	"TessControlShader",	ri::TYPE_SHADER			},
	{ 0xa1bf7153,	"TessEvaluationShader",	ri::TYPE_SHADER			},
	{ 0x6c1415d9,	"ComputeShader",		ri::TYPE_SHADER			},
	{ 0x72863a54,	"ShaderProgram",		ri::TYPE_SHADERPROGRAM	},
	{ 0xb4efc08d,	"ShaderSource",			ri::TYPE_SHADERSOURCE	},
	{ 0xaee4380a,	"SpirVAssemblySource",	ri::TYPE_SPIRVSOURCE	},
	{ 0xff265913,	"InfoLog",				ri::TYPE_INFOLOG		},
	{ 0x84159b73,	"EglConfig",			ri::TYPE_EGLCONFIG		},
	{ 0xdd34391f,	"EglConfigSet",			ri::TYPE_EGLCONFIGSET	},
	{ 0xebbb3aba,	"Section",				ri::TYPE_SECTION		},
	{ 0xa0f15677,	"KernelSource",			ri::TYPE_KERNELSOURCE	},
	{ 0x1ee9083a,	"CompileInfo",			ri::TYPE_COMPILEINFO	},
	{ 0xf1004023,	"SampleList",			ri::TYPE_SAMPLELIST		},
	{ 0xf0feae93,	"SampleInfo",			ri::TYPE_SAMPLEINFO		},
	{ 0x2aa6f14e,	"ValueInfo",			ri::TYPE_VALUEINFO		},
	{ 0xd09429e7,	"Sample",				ri::TYPE_SAMPLE			},
	{ 0x0e4a4722,	"Value",				ri::TYPE_SAMPLEVALUE	},
};

static const EnumMapEntry s_imageFormatMap[] =
{
	{ 0xcc4ffac8,	"RGB888",		ri::Image::FORMAT_RGB888	},
	{ 0x20dcb0c1,	"RGBA8888",		ri::Image::FORMAT_RGBA8888	}
};

static const EnumMapEntry s_compressionMap[] =
{
	{ 0x7c89bbd5,	"None",			ri::Image::COMPRESSION_NONE	},
	{ 0x0b88118a,	"PNG",			ri::Image::COMPRESSION_PNG	}
};

static const EnumMapEntry s_shaderTypeFromTagMap[] =
{
	{ 0x1181fa5a,	"VertexShader",			ri::Shader::SHADERTYPE_VERTEX			},
	{ 0xa93daef0,	"FragmentShader",		ri::Shader::SHADERTYPE_FRAGMENT			},
	{ 0x8f066128,	"GeometryShader",		ri::Shader::SHADERTYPE_GEOMETRY			},
	{ 0x235a931c,	"TessControlShader",	ri::Shader::SHADERTYPE_TESS_CONTROL		},
	{ 0xa1bf7153,	"TessEvaluationShader",	ri::Shader::SHADERTYPE_TESS_EVALUATION	},
	{ 0x6c1415d9,	"ComputeShader",		ri::Shader::SHADERTYPE_COMPUTE			},
};

static const EnumMapEntry s_testTypeMap[] =
{
	{ 0x7fa80959,	"SelfValidate",	TESTCASETYPE_SELF_VALIDATE	},
	{ 0xdb797567,	"Capability",	TESTCASETYPE_CAPABILITY		},
	{ 0x2ca3ec10,	"Accuracy",		TESTCASETYPE_ACCURACY		},
	{ 0xa48ac277,	"Performance",	TESTCASETYPE_PERFORMANCE	}
};

static const EnumMapEntry s_logVersionMap[] =
{
	{ 0x0b7dac93,	"0.2.0",		TESTLOGVERSION_0_2_0	},
	{ 0x0b7db0d4,	"0.3.0",		TESTLOGVERSION_0_3_0	},
	{ 0x0b7db0d5,	"0.3.1",		TESTLOGVERSION_0_3_1	},
	{ 0x0b7db0d6,	"0.3.2",		TESTLOGVERSION_0_3_2	},
	{ 0x0b7db0d7,	"0.3.3",		TESTLOGVERSION_0_3_3	},
	{ 0x0b7db0d8,	"0.3.4",		TESTLOGVERSION_0_3_4	}
};

static const EnumMapEntry s_sampleValueTagMap[] =
{
	{ 0xddf2d0d1,	"Predictor",	ri::ValueInfo::VALUETAG_PREDICTOR	},
	{ 0x9bee2c34,	"Response",		ri::ValueInfo::VALUETAG_RESPONSE	},
};

#if defined(DE_DEBUG)
static void printHashes (const char* name, const EnumMapEntry* entries, int numEntries)
{
	printf("%s:\n", name);

	for (int ndx = 0; ndx < numEntries; ndx++)
		printf("0x%08x\t%s\n", deStringHash(entries[ndx].name), entries[ndx].name);

	printf("\n");
}

#define PRINT_HASHES(MAP) printHashes(#MAP, MAP, DE_LENGTH_OF_ARRAY(MAP))

void TestResultParser_printHashes (void)
{
	PRINT_HASHES(s_statusCodeMap);
	PRINT_HASHES(s_resultItemMap);
	PRINT_HASHES(s_imageFormatMap);
	PRINT_HASHES(s_compressionMap);
	PRINT_HASHES(s_shaderTypeFromTagMap);
	PRINT_HASHES(s_testTypeMap);
	PRINT_HASHES(s_logVersionMap);
	PRINT_HASHES(s_sampleValueTagMap);
}
#endif

static inline int getEnumValue (const char* enumName, const EnumMapEntry* entries, int numEntries, const char* name)
{
	deUint32 hash = deStringHash(name);

	for (int ndx = 0; ndx < numEntries; ndx++)
	{
		if (entries[ndx].hash == hash && deStringEqual(entries[ndx].name, name))
			return entries[ndx].value;
	}

	throw TestResultParseError(string("Could not map '") + name + "' to " + enumName);
}

TestStatusCode getTestStatusCode (const char* statusCode)
{
	return (TestStatusCode)getEnumValue("status code", s_statusCodeMap, DE_LENGTH_OF_ARRAY(s_statusCodeMap), statusCode);
}

static ri::Type getResultItemType (const char* elemName)
{
	return (ri::Type)getEnumValue("result item type", s_resultItemMap, DE_LENGTH_OF_ARRAY(s_resultItemMap), elemName);
}

static ri::Image::Format getImageFormat (const char* imageFormat)
{
	return (ri::Image::Format)getEnumValue("image format", s_imageFormatMap, DE_LENGTH_OF_ARRAY(s_imageFormatMap), imageFormat);
}

static ri::Image::Compression getImageCompression (const char* compression)
{
	return (ri::Image::Compression)getEnumValue("image compression", s_compressionMap, DE_LENGTH_OF_ARRAY(s_compressionMap), compression);
}

static ri::Shader::ShaderType getShaderTypeFromTagName (const char* shaderType)
{
	return (ri::Shader::ShaderType)getEnumValue("shader type", s_shaderTypeFromTagMap, DE_LENGTH_OF_ARRAY(s_shaderTypeFromTagMap), shaderType);
}

static TestCaseType getTestCaseType (const char* caseType)
{
	return (TestCaseType)getEnumValue("test case type", s_testTypeMap, DE_LENGTH_OF_ARRAY(s_testTypeMap), caseType);
}

static TestLogVersion getTestLogVersion (const char* logVersion)
{
	return (TestLogVersion)getEnumValue("test log version", s_logVersionMap, DE_LENGTH_OF_ARRAY(s_logVersionMap), logVersion);
}

static ri::ValueInfo::ValueTag getSampleValueTag (const char* tag)
{
	return (ri::ValueInfo::ValueTag)getEnumValue("sample value tag", s_sampleValueTagMap, DE_LENGTH_OF_ARRAY(s_sampleValueTagMap), tag);
}

static TestCaseType getTestCaseTypeFromPath (const char* casePath)
{
	if (deStringBeginsWith(casePath, "dEQP-GLES2."))
	{
		const char* group = casePath+11;
		if (deStringBeginsWith(group, "capability."))
			return TESTCASETYPE_CAPABILITY;
		else if (deStringBeginsWith(group, "accuracy."))
			return TESTCASETYPE_ACCURACY;
		else if (deStringBeginsWith(group, "performance."))
			return TESTCASETYPE_PERFORMANCE;
	}

	return TESTCASETYPE_SELF_VALIDATE;
}

static ri::NumericValue getNumericValue (const std::string& value)
{
	const bool	isFloat		= value.find('.') != std::string::npos || value.find('e') != std::string::npos;

	if (isFloat)
	{
		const double num = toDouble(stripLeadingWhitespace(value.c_str()));
		return ri::NumericValue(num);
	}
	else
	{
		const deInt64 num = toInt64(stripLeadingWhitespace(value.c_str()));
		return ri::NumericValue(num);
	}
}

TestResultParser::TestResultParser (void)
	: m_result				(DE_NULL)
	, m_state				(STATE_NOT_INITIALIZED)
	, m_logVersion			(TESTLOGVERSION_LAST)
	, m_curItemList			(DE_NULL)
	, m_base64DecodeOffset	(0)
{
}

TestResultParser::~TestResultParser (void)
{
}

void TestResultParser::clear (void)
{
	m_xmlParser.clear();
	m_itemStack.clear();

	m_result				= DE_NULL;
	m_state					= STATE_NOT_INITIALIZED;
	m_logVersion			= TESTLOGVERSION_LAST;
	m_curItemList			= DE_NULL;
	m_base64DecodeOffset	= 0;
	m_curNumValue.clear();
}

void TestResultParser::init (TestCaseResult* dstResult)
{
	clear();
	m_result		= dstResult;
	m_state			= STATE_INITIALIZED;
	m_curItemList	= &dstResult->resultItems;
}

TestResultParser::ParseResult TestResultParser::parse (const deUint8* bytes, int numBytes)
{
	DE_ASSERT(m_result && m_state != STATE_NOT_INITIALIZED);

	try
	{
		bool resultChanged = false;

		m_xmlParser.feed(bytes, numBytes);

		for (;;)
		{
			xml::Element curElement = m_xmlParser.getElement();

			if (curElement == xml::ELEMENT_INCOMPLETE	||
				curElement == xml::ELEMENT_END_OF_STRING)
				break;

			switch (curElement)
			{
				case xml::ELEMENT_START:	handleElementStart();		break;
				case xml::ELEMENT_END:		handleElementEnd();			break;
				case xml::ELEMENT_DATA:		handleData();				break;

				default:
					DE_ASSERT(false);
			}

			resultChanged = true;
			m_xmlParser.advance();
		}

		if (m_xmlParser.getElement() == xml::ELEMENT_END_OF_STRING)
		{
			if (m_state != STATE_TEST_CASE_RESULT_ENDED)
				throw TestResultParseError("Unexpected end of log data");

			return PARSERESULT_COMPLETE;
		}
		else
			return resultChanged ? PARSERESULT_CHANGED
								 : PARSERESULT_NOT_CHANGED;
	}
	catch (const TestResultParseError& e)
	{
		// Set error code to result.
		m_result->statusCode	= TESTSTATUSCODE_INTERNAL_ERROR;
		m_result->statusDetails	= e.what();

		return PARSERESULT_ERROR;
	}
	catch (const xml::ParseError& e)
	{
		// Set error code to result.
		m_result->statusCode	= TESTSTATUSCODE_INTERNAL_ERROR;
		m_result->statusDetails	= e.what();

		return PARSERESULT_ERROR;
	}
}

const char* TestResultParser::getAttribute (const char* name)
{
	if (!m_xmlParser.hasAttribute(name))
		throw TestResultParseError(string("Missing attribute '") + name + "' in <" + m_xmlParser.getElementName() + ">");

	return m_xmlParser.getAttribute(name);
}

ri::Item* TestResultParser::getCurrentItem (void)
{
	return !m_itemStack.empty() ? m_itemStack.back() : DE_NULL;
}

ri::List* TestResultParser::getCurrentItemList (void)
{
	DE_ASSERT(m_curItemList);
	return m_curItemList;
}

void TestResultParser::updateCurrentItemList (void)
{
	m_curItemList = DE_NULL;

	for (vector<ri::Item*>::reverse_iterator i = m_itemStack.rbegin(); i != m_itemStack.rend(); i++)
	{
		ri::Item*	item	= *i;
		ri::Type	type	= item->getType();

		if (type == ri::TYPE_IMAGESET)
			m_curItemList = &static_cast<ri::ImageSet*>(item)->images;
		else if (type == ri::TYPE_SECTION)
			m_curItemList = &static_cast<ri::Section*>(item)->items;
		else if (type == ri::TYPE_EGLCONFIGSET)
			m_curItemList = &static_cast<ri::EglConfigSet*>(item)->configs;
		else if (type == ri::TYPE_SHADERPROGRAM)
			m_curItemList = &static_cast<ri::ShaderProgram*>(item)->shaders;

		if (m_curItemList)
			break;
	}

	if (!m_curItemList)
		m_curItemList = &m_result->resultItems;
}

void TestResultParser::pushItem (ri::Item* item)
{
	m_itemStack.push_back(item);
	updateCurrentItemList();
}

void TestResultParser::popItem (void)
{
	m_itemStack.pop_back();
	updateCurrentItemList();
}

void TestResultParser::handleElementStart (void)
{
	const char* elemName = m_xmlParser.getElementName();

	if (m_state == STATE_INITIALIZED)
	{
		// Expect TestCaseResult.
		if (!deStringEqual(elemName, "TestCaseResult"))
			throw TestResultParseError(string("Expected <TestCaseResult>, got <") + elemName + ">");

		const char* version = getAttribute("Version");
		m_logVersion = getTestLogVersion(version);
		// \note Currently assumed that all known log versions are supported.

		m_result->casePath	= getAttribute("CasePath");
		m_result->caseType	= TESTCASETYPE_SELF_VALIDATE;

		if (m_xmlParser.hasAttribute("CaseType"))
			m_result->caseType = getTestCaseType(m_xmlParser.getAttribute("CaseType"));
		else
		{
			// Do guess based on path for legacy log files.
			if (m_logVersion >= TESTLOGVERSION_0_3_2)
				throw TestResultParseError("Missing CaseType attribute in <TestCaseResult>");
			m_result->caseType = getTestCaseTypeFromPath(m_result->casePath.c_str());
		}

		m_state = STATE_IN_TEST_CASE_RESULT;
	}
	else
	{
		ri::List*	curList		= getCurrentItemList();
		ri::Type	itemType	= getResultItemType(elemName);
		ri::Item*	item		= DE_NULL;
		ri::Item*	parentItem	= getCurrentItem();
		ri::Type	parentType	= parentItem ? parentItem->getType() : ri::TYPE_LAST;

		switch (itemType)
		{
			case ri::TYPE_RESULT:
			{
				ri::Result* result = curList->allocItem<ri::Result>();
				result->statusCode = getTestStatusCode(getAttribute("StatusCode"));
				item = result;
				break;
			}

			case ri::TYPE_TEXT:
				item = curList->allocItem<ri::Text>();
				break;

			case ri::TYPE_SECTION:
			{
				ri::Section* section = curList->allocItem<ri::Section>();
				section->name			= getAttribute("Name");
				section->description	= getAttribute("Description");
				item = section;
				break;
			}

			case ri::TYPE_NUMBER:
			{
				ri::Number* number = curList->allocItem<ri::Number>();
				number->name		= getAttribute("Name");
				number->description	= getAttribute("Description");
				number->unit		= getAttribute("Unit");

				if (m_xmlParser.hasAttribute("Tag"))
					number->tag = m_xmlParser.getAttribute("Tag");

				item = number;

				m_curNumValue.clear();
				break;
			}

			case ri::TYPE_IMAGESET:
			{
				ri::ImageSet* imageSet = curList->allocItem<ri::ImageSet>();
				imageSet->name			= getAttribute("Name");
				imageSet->description	= getAttribute("Description");
				item = imageSet;
				break;
			}

			case ri::TYPE_IMAGE:
			{
				ri::Image* image = curList->allocItem<ri::Image>();
				image->name			= getAttribute("Name");
				image->description	= getAttribute("Description");
				image->width		= toInt(getAttribute("Width"));
				image->height		= toInt(getAttribute("Height"));
				image->format		= getImageFormat(getAttribute("Format"));
				image->compression	= getImageCompression(getAttribute("CompressionMode"));
				item = image;
				break;
			}

			case ri::TYPE_SHADERPROGRAM:
			{
				ri::ShaderProgram* shaderProgram = curList->allocItem<ri::ShaderProgram>();
				shaderProgram->linkStatus = toBool(getAttribute("LinkStatus"));
				item = shaderProgram;
				break;
			}

			case ri::TYPE_SHADER:
			{
				if (parentType != ri::TYPE_SHADERPROGRAM)
					throw TestResultParseError(string("<") + elemName + "> outside of <ShaderProgram>");

				ri::Shader* shader = curList->allocItem<ri::Shader>();

				shader->shaderType		= getShaderTypeFromTagName(elemName);
				shader->compileStatus	= toBool(getAttribute("CompileStatus"));

				item = shader;
				break;
			}

			case ri::TYPE_SPIRVSOURCE:
			{
				if (parentType != ri::TYPE_SHADERPROGRAM)
					throw TestResultParseError(string("<") + elemName + "> outside of <ShaderProgram>");
				item = curList->allocItem<ri::SpirVSource>();
				break;
			}

			case ri::TYPE_SHADERSOURCE:
				if (parentType == ri::TYPE_SHADER)
					item = &static_cast<ri::Shader*>(parentItem)->source;
				else
					throw TestResultParseError("Unexpected <ShaderSource>");
				break;

			case ri::TYPE_INFOLOG:
				if (parentType == ri::TYPE_SHADERPROGRAM)
					item = &static_cast<ri::ShaderProgram*>(parentItem)->linkInfoLog;
				else if (parentType == ri::TYPE_SHADER)
					item = &static_cast<ri::Shader*>(parentItem)->infoLog;
				else if (parentType == ri::TYPE_COMPILEINFO)
					item = &static_cast<ri::CompileInfo*>(parentItem)->infoLog;
				else
					throw TestResultParseError("Unexpected <InfoLog>");
				break;

			case ri::TYPE_KERNELSOURCE:
				item = curList->allocItem<ri::KernelSource>();
				break;

			case ri::TYPE_COMPILEINFO:
			{
				ri::CompileInfo* info = curList->allocItem<ri::CompileInfo>();
				info->name			= getAttribute("Name");
				info->description	= getAttribute("Description");
				info->compileStatus	= toBool(getAttribute("CompileStatus"));
				item = info;
				break;
			}

			case ri::TYPE_EGLCONFIGSET:
			{
				ri::EglConfigSet* set = curList->allocItem<ri::EglConfigSet>();
				set->name			= getAttribute("Name");
				set->description	= m_xmlParser.hasAttribute("Description") ? m_xmlParser.getAttribute("Description") : "";
				item = set;
				break;
			}

			case ri::TYPE_EGLCONFIG:
			{
				ri::EglConfig* config = curList->allocItem<ri::EglConfig>();
				config->bufferSize				= toInt(getAttribute("BufferSize"));
				config->redSize					= toInt(getAttribute("RedSize"));
				config->greenSize				= toInt(getAttribute("GreenSize"));
				config->blueSize				= toInt(getAttribute("BlueSize"));
				config->luminanceSize			= toInt(getAttribute("LuminanceSize"));
				config->alphaSize				= toInt(getAttribute("AlphaSize"));
				config->alphaMaskSize			= toInt(getAttribute("AlphaMaskSize"));
				config->bindToTextureRGB		= toBool(getAttribute("BindToTextureRGB"));
				config->bindToTextureRGBA		= toBool(getAttribute("BindToTextureRGBA"));
				config->colorBufferType			= getAttribute("ColorBufferType");
				config->configCaveat			= getAttribute("ConfigCaveat");
				config->configID				= toInt(getAttribute("ConfigID"));
				config->conformant				= getAttribute("Conformant");
				config->depthSize				= toInt(getAttribute("DepthSize"));
				config->level					= toInt(getAttribute("Level"));
				config->maxPBufferWidth			= toInt(getAttribute("MaxPBufferWidth"));
				config->maxPBufferHeight		= toInt(getAttribute("MaxPBufferHeight"));
				config->maxPBufferPixels		= toInt(getAttribute("MaxPBufferPixels"));
				config->maxSwapInterval			= toInt(getAttribute("MaxSwapInterval"));
				config->minSwapInterval			= toInt(getAttribute("MinSwapInterval"));
				config->nativeRenderable		= toBool(getAttribute("NativeRenderable"));
				config->renderableType			= getAttribute("RenderableType");
				config->sampleBuffers			= toInt(getAttribute("SampleBuffers"));
				config->samples					= toInt(getAttribute("Samples"));
				config->stencilSize				= toInt(getAttribute("StencilSize"));
				config->surfaceTypes			= getAttribute("SurfaceTypes");
				config->transparentType			= getAttribute("TransparentType");
				config->transparentRedValue		= toInt(getAttribute("TransparentRedValue"));
				config->transparentGreenValue	= toInt(getAttribute("TransparentGreenValue"));
				config->transparentBlueValue	= toInt(getAttribute("TransparentBlueValue"));
				item = config;
				break;
			}

			case ri::TYPE_SAMPLELIST:
			{
				ri::SampleList* list = curList->allocItem<ri::SampleList>();
				list->name			= getAttribute("Name");
				list->description	= getAttribute("Description");
				item = list;
				break;
			}

			case ri::TYPE_SAMPLEINFO:
			{
				if (parentType != ri::TYPE_SAMPLELIST)
					throw TestResultParseError("<SampleInfo> outside of <SampleList>");

				ri::SampleList*	list	= static_cast<ri::SampleList*>(parentItem);
				ri::SampleInfo*	info	= &list->sampleInfo;

				item = info;
				break;
			}

			case ri::TYPE_VALUEINFO:
			{
				if (parentType != ri::TYPE_SAMPLEINFO)
					throw TestResultParseError("<ValueInfo> outside of <SampleInfo>");

				ri::SampleInfo*	sampleInfo	= static_cast<ri::SampleInfo*>(parentItem);
				ri::ValueInfo*	valueInfo	= sampleInfo->valueInfos.allocItem<ri::ValueInfo>();

				valueInfo->name			= getAttribute("Name");
				valueInfo->description	= getAttribute("Description");
				valueInfo->tag			= getSampleValueTag(getAttribute("Tag"));

				if (m_xmlParser.hasAttribute("Unit"))
					valueInfo->unit = getAttribute("Unit");

				item = valueInfo;
				break;
			}

			case ri::TYPE_SAMPLE:
			{
				if (parentType != ri::TYPE_SAMPLELIST)
					throw TestResultParseError("<Sample> outside of <SampleList>");

				ri::SampleList*	list	= static_cast<ri::SampleList*>(parentItem);
				ri::Sample*		sample	= list->samples.allocItem<ri::Sample>();

				item = sample;
				break;
			}

			case ri::TYPE_SAMPLEVALUE:
			{
				if (parentType != ri::TYPE_SAMPLE)
					throw TestResultParseError("<Value> outside of <Sample>");

				ri::Sample*			sample	= static_cast<ri::Sample*>(parentItem);
				ri::SampleValue*	value	= sample->values.allocItem<ri::SampleValue>();

				item = value;
				break;
			}

			default:
				throw TestResultParseError(string("Unsupported element '") + elemName + ("'"));
		}

		DE_ASSERT(item);
		pushItem(item);

		// Reset base64 decoding offset.
		m_base64DecodeOffset = 0;
	}
}

void TestResultParser::handleElementEnd (void)
{
	const char* elemName = m_xmlParser.getElementName();

	if (m_state != STATE_IN_TEST_CASE_RESULT)
		throw TestResultParseError(string("Unexpected </") + elemName + "> outside of <TestCaseResult>");

	if (deStringEqual(elemName, "TestCaseResult"))
	{
		// Logs from buggy test cases may contain invalid XML.
		// DE_ASSERT(getCurrentItem() == DE_NULL);
		// \todo [2012-11-22 pyry] Log warning.

		m_state = STATE_TEST_CASE_RESULT_ENDED;
	}
	else
	{
		ri::Type	itemType	= getResultItemType(elemName);
		ri::Item*	curItem		= getCurrentItem();

		if (!curItem || itemType != curItem->getType())
			throw TestResultParseError(string("Unexpected </") + elemName + ">");

		if (itemType == ri::TYPE_RESULT)
		{
			ri::Result* result = static_cast<ri::Result*>(curItem);
			m_result->statusCode	= result->statusCode;
			m_result->statusDetails	= result->details;
		}
		else if (itemType == ri::TYPE_NUMBER)
		{
			// Parse value for number.
			ri::Number*	number	= static_cast<ri::Number*>(curItem);
			number->value = getNumericValue(m_curNumValue);
			m_curNumValue.clear();
		}
		else if (itemType == ri::TYPE_SAMPLEVALUE)
		{
			ri::SampleValue* value = static_cast<ri::SampleValue*>(curItem);
			value->value = getNumericValue(m_curNumValue);
			m_curNumValue.clear();
		}

		popItem();
	}
}

void TestResultParser::handleData (void)
{
	ri::Item*	curItem		= getCurrentItem();
	ri::Type	type		= curItem ? curItem->getType() : ri::TYPE_LAST;

	switch (type)
	{
		case ri::TYPE_RESULT:
			m_xmlParser.appendDataStr(static_cast<ri::Result*>(curItem)->details);
			break;

		case ri::TYPE_TEXT:
			m_xmlParser.appendDataStr(static_cast<ri::Text*>(curItem)->text);
			break;

		case ri::TYPE_SHADERSOURCE:
			m_xmlParser.appendDataStr(static_cast<ri::ShaderSource*>(curItem)->source);
			break;

		case ri::TYPE_SPIRVSOURCE:
			m_xmlParser.appendDataStr(static_cast<ri::SpirVSource*>(curItem)->source);
			break;

		case ri::TYPE_INFOLOG:
			m_xmlParser.appendDataStr(static_cast<ri::InfoLog*>(curItem)->log);
			break;

		case ri::TYPE_KERNELSOURCE:
			m_xmlParser.appendDataStr(static_cast<ri::KernelSource*>(curItem)->source);
			break;

		case ri::TYPE_NUMBER:
		case ri::TYPE_SAMPLEVALUE:
			m_xmlParser.appendDataStr(m_curNumValue);
			break;

		case ri::TYPE_IMAGE:
		{
			ri::Image* image = static_cast<ri::Image*>(curItem);

			// Base64 decode.
			int numBytesIn = m_xmlParser.getDataSize();

			for (int inNdx = 0; inNdx < numBytesIn; inNdx++)
			{
				deUint8		byte		= m_xmlParser.getDataByte(inNdx);
				deUint8		decodedBits	= 0;

				if (de::inRange<deInt8>(byte, 'A', 'Z'))
					decodedBits = (deUint8)(byte - 'A');
				else if (de::inRange<deInt8>(byte, 'a', 'z'))
					decodedBits = (deUint8)(('Z'-'A'+1) + (byte-'a'));
				else if (de::inRange<deInt8>(byte, '0', '9'))
					decodedBits = (deUint8)(('Z'-'A'+1) + ('z'-'a'+1) + (byte-'0'));
				else if (byte == '+')
					decodedBits = ('Z'-'A'+1) + ('z'-'a'+1) + ('9'-'0'+1);
				else if (byte == '/')
					decodedBits = ('Z'-'A'+1) + ('z'-'a'+1) + ('9'-'0'+2);
				else if (byte == '=')
				{
					// Padding at end - remove last byte.
					if (image->data.empty())
						throw TestResultParseError("Malformed base64 data");
					image->data.pop_back();
					continue;
				}
				else
					continue; // Not an B64 input character.

				int phase = m_base64DecodeOffset % 4;

				if (phase == 0)
					image->data.resize(image->data.size()+3, 0);

				if ((int)image->data.size() < (m_base64DecodeOffset>>2)*3 + 3)
					throw TestResultParseError("Malformed base64 data");
				deUint8* outPtr = &image->data[(m_base64DecodeOffset>>2)*3];

				switch (phase)
				{
					case 0: outPtr[0] |= (deUint8)(decodedBits<<2);													break;
					case 1: outPtr[0] |= (deUint8)(decodedBits>>4);	outPtr[1] |= (deUint8)((decodedBits&0xF)<<4);	break;
					case 2: outPtr[1] |= (deUint8)(decodedBits>>2);	outPtr[2] |= (deUint8)((decodedBits&0x3)<<6);	break;
					case 3: outPtr[2] |= decodedBits;																break;
					default:
						DE_ASSERT(false);
				}

				m_base64DecodeOffset += 1;
			}

			break;
		}

		default:
			// Just ignore data.
			break;
	}
}

//! Helper for parsing TestCaseResult from TestCaseResultData.
void parseTestCaseResultFromData (TestResultParser* parser, TestCaseResult* result, const TestCaseResultData& data)
{
	DE_ASSERT(result->resultItems.getNumItems() == 0);

	// Initialize status codes etc. from data.
	result->casePath		= data.getTestCasePath();
	result->caseType		= TESTCASETYPE_SELF_VALIDATE;
	result->statusCode		= data.getStatusCode();
	result->statusDetails	= data.getStatusDetails();

	if (data.getDataSize() > 0)
	{
		parser->init(result);

		const TestResultParser::ParseResult parseResult = parser->parse(data.getData(), data.getDataSize());

		if (result->statusCode == TESTSTATUSCODE_LAST)
		{
			result->statusCode = TESTSTATUSCODE_INTERNAL_ERROR;

			if (parseResult == TestResultParser::PARSERESULT_ERROR)
				result->statusDetails = "Test case result parsing failed";
			else if (parseResult != TestResultParser::PARSERESULT_COMPLETE)
				result->statusDetails = "Incomplete test case result";
			else
				result->statusDetails = "Test case result is missing <Result> item";
		}
	}
	else if (result->statusCode == TESTSTATUSCODE_LAST)
	{
		result->statusCode		= TESTSTATUSCODE_TERMINATED;
		result->statusDetails	= "Empty test case result";
	}

	if (result->casePath.empty())
		throw Error("Empty test case path in result");

	if (result->caseType == TESTCASETYPE_LAST)
		throw Error("Invalid test case type in result");

	DE_ASSERT(result->statusCode != TESTSTATUSCODE_LAST);
}

} // xe
