/*-------------------------------------------------------------------------
 * 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 list parser.
 *//*--------------------------------------------------------------------*/

#include "xeTestCaseListParser.hpp"
#include "deString.h"

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

namespace xe
{

static TestCaseType getTestCaseType (const char* caseType)
{
	// \todo [2012-06-11 pyry] Use hashes for speedup.
	static const struct
	{
		const char*		name;
		TestCaseType	caseType;
	} s_caseTypeMap[] =
	{
		{ "SelfValidate",	TESTCASETYPE_SELF_VALIDATE	},
		{ "Capability",		TESTCASETYPE_CAPABILITY		},
		{ "Accuracy",		TESTCASETYPE_ACCURACY		},
		{ "Performance",	TESTCASETYPE_PERFORMANCE	}
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_caseTypeMap); ndx++)
	{
		if (deStringEqual(caseType, s_caseTypeMap[ndx].name))
			return s_caseTypeMap[ndx].caseType;
	}

	XE_FAIL((string("Unknown test case type '") + caseType + "'").c_str());
}

TestCaseListParser::TestCaseListParser (void)
	: m_root(DE_NULL)
{
}

TestCaseListParser::~TestCaseListParser (void)
{
}

void TestCaseListParser::clear (void)
{
	m_xmlParser.clear();
	m_nodeStack.clear();
	m_root = DE_NULL;
}

void TestCaseListParser::init (TestGroup* rootGroup)
{
	clear();
	m_root = rootGroup;
}

void TestCaseListParser::parse (const deUint8* bytes, int numBytes)
{
	DE_ASSERT(m_root);
	m_xmlParser.feed(bytes, numBytes);

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

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

		if (element == xml::ELEMENT_START || element == xml::ELEMENT_END)
		{
			bool		isStart		= element == xml::ELEMENT_START;
			const char* elemName	= m_xmlParser.getElementName();

			if (deStringEqual(elemName, "TestCase"))
			{
				if (isStart)
				{
					XE_CHECK_MSG(!m_nodeStack.empty(), "<TestCase> outside of <TestCaseList>");

					TestNode*		parent		= m_nodeStack.back();
					const char*		name		= m_xmlParser.hasAttribute("Name")			? m_xmlParser.getAttribute("Name")			: DE_NULL;
					const char*		description	= m_xmlParser.hasAttribute("Description")	? m_xmlParser.getAttribute("Description")	: DE_NULL;
					const char*		caseType	= m_xmlParser.hasAttribute("CaseType")		? m_xmlParser.getAttribute("CaseType")		: DE_NULL;

					XE_CHECK_MSG(name && description && caseType, "Missing attribute in <TestCase>");
					XE_CHECK_MSG(parent->getNodeType() == TESTNODETYPE_GROUP, "Only TestGroups are allowed to have child nodes");

					bool			isGroup		= deStringEqual(caseType, "TestGroup") == DE_TRUE;
					TestNode*		node		= isGroup ? static_cast<TestNode*>(static_cast<TestGroup*>(parent)->createGroup(name, description))
														  : static_cast<TestNode*>(static_cast<TestGroup*>(parent)->createCase(getTestCaseType(caseType), name, description));

					m_nodeStack.push_back(node);
				}
				else
				{
					XE_CHECK_MSG(m_nodeStack.size() >= 2, "Unexpected </TestCase>");
					m_nodeStack.pop_back();
				}
			}
			else if (deStringEqual(elemName, "TestCaseList"))
			{
				if (isStart)
				{
					XE_CHECK_MSG(m_nodeStack.empty(), "Unexpected <TestCaseList>");
					m_nodeStack.push_back(m_root);
				}
				else
				{
					XE_CHECK_MSG(m_nodeStack.size() == 1, "Unexpected </TestCaseList>");
					m_nodeStack.pop_back();
				}
			}
			else
				XE_FAIL((string("Unexpected <") + elemName + ">").c_str());
		}
		else if (element != xml::ELEMENT_DATA)
			DE_ASSERT(false); // \note Data elements are just ignored, they should be whitespace anyway.

		m_xmlParser.advance();
	}
}

} // xe
