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

#include "xeTestCase.hpp"

using std::vector;

namespace xe
{

const char* getTestCaseTypeName (TestCaseType caseType)
{
	switch (caseType)
	{
		case TESTCASETYPE_SELF_VALIDATE:	return "SelfValidate";
		case TESTCASETYPE_CAPABILITY:		return "Capability";
		case TESTCASETYPE_ACCURACY:			return "Accuracy";
		case TESTCASETYPE_PERFORMANCE:		return "Performance";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

static inline int getFirstComponentLength (const char* path)
{
	int compLen = 0;
	while (path[compLen] != 0 && path[compLen] != '.')
		compLen++;
	return compLen;
}

static bool compareNameToPathComponent (const char* name, const char* path, int compLen)
{
	for (int pos = 0; pos < compLen; pos++)
	{
		if (name[pos] != path[pos])
			return false;
	}

	if (name[compLen] != 0)
		return false;

	return true;
}

static void splitPath (const char* path, std::vector<std::string>& components)
{
	std::string	pathStr		(path);
	int			compStart	= 0;

	for (int pos = 0; pos < (int)pathStr.length(); pos++)
	{
		if (pathStr[pos] == '.')
		{
			components.push_back(pathStr.substr(compStart, pos-compStart));
			compStart = pos+1;
		}
	}

	DE_ASSERT(compStart < (int)pathStr.length());
	components.push_back(pathStr.substr(compStart));
}

// TestNode

TestNode::TestNode (TestGroup* parent, TestNodeType nodeType, const char* name)
	: m_parent		(parent)
	, m_nodeType	(nodeType)
	, m_name		(name)
{
	if (m_parent)
	{
		// Verify that the name is unique.
		if (parent->m_childNames.find(name) != parent->m_childNames.end())
			throw Error(std::string("Duplicate node '") + name + "' in '" + parent->getFullPath());

		m_parent->m_children.push_back(this);
		m_parent->m_childNames.insert(name);
	}
}

void TestNode::getFullPath (std::string& dst) const
{
	dst.clear();

	int				nameLen	= 0;
	const TestNode*	curNode	= this;

	for (;;)
	{
		nameLen += (int)curNode->m_name.length();

		DE_ASSERT(curNode->m_parent);
		if (curNode->m_parent->getNodeType() != TESTNODETYPE_ROOT)
		{
			nameLen += 1;
			curNode  = curNode->m_parent;
		}
		else
			break;
	}

	dst.resize(nameLen);

	curNode = this;
	int pos = nameLen;

	for (;;)
	{
		std::copy(curNode->m_name.begin(), curNode->m_name.end(), dst.begin()+(pos-curNode->m_name.length()));
		pos -= (int)curNode->m_name.length();

		DE_ASSERT(curNode->m_parent);
		if (curNode->m_parent->getNodeType() != TESTNODETYPE_ROOT)
		{
			dst[--pos] = '.';
			curNode = curNode->m_parent;
		}
		else
			break;
	}
}

const TestNode* TestNode::find (const char* path) const
{
	if (m_nodeType == TESTNODETYPE_ROOT)
	{
		// Don't need to consider current node.
		return static_cast<const TestGroup*>(this)->findChildNode(path);
	}
	else
	{
		// Check if first component matches this node.
		int compLen = getFirstComponentLength(path);
		XE_CHECK(compLen > 0);

		if (compareNameToPathComponent(getName(), path, compLen))
		{
			if (path[compLen] == 0)
				return this;
			else if (getNodeType() == TESTNODETYPE_GROUP)
				return static_cast<const TestGroup*>(this)->findChildNode(path + compLen + 1);
			else
				return DE_NULL;
		}
		else
			return DE_NULL;
	}
}

TestNode* TestNode::find (const char* path)
{
	return const_cast<TestNode*>(const_cast<const TestNode*>(this)->find(path));
}

// TestGroup

TestGroup::TestGroup (TestGroup* parent, TestNodeType nodeType, const char* name)
	: TestNode(parent, nodeType, name)
{
	DE_ASSERT(nodeType == TESTNODETYPE_GROUP || nodeType == TESTNODETYPE_ROOT);
	DE_ASSERT(!parent == (nodeType == TESTNODETYPE_ROOT));
}

TestGroup::~TestGroup (void)
{
	for (std::vector<TestNode*>::iterator i = m_children.begin(); i != m_children.end(); i++)
		delete *i;
}

TestGroup* TestGroup::createGroup (const char* name)
{
	return new TestGroup(this, TESTNODETYPE_GROUP, name);
}

TestCase* TestGroup::createCase (TestCaseType caseType, const char* name)
{
	return TestCase::createAsChild(this, caseType, name);
}

const TestNode* TestGroup::findChildNode (const char* path) const
{
	int compLen = getFirstComponentLength(path);
	XE_CHECK(compLen > 0);

	// Try to find matching children.
	const TestNode* matchingNode = DE_NULL;
	for (vector<TestNode*>::const_iterator iter = m_children.begin(); iter != m_children.end(); iter++)
	{
		if (compareNameToPathComponent((*iter)->getName(), path, compLen))
		{
			matchingNode = *iter;
			break;
		}
	}

	if (matchingNode)
	{
		if (path[compLen] == 0)
			return matchingNode; // Last element in path, return matching node.
		else if (matchingNode->getNodeType() == TESTNODETYPE_GROUP)
			return static_cast<const TestGroup*>(matchingNode)->findChildNode(path + compLen + 1);
		else
			return DE_NULL;
	}
	else
		return DE_NULL;
}

// TestRoot

TestRoot::TestRoot (void)
	: TestGroup(DE_NULL, TESTNODETYPE_ROOT, "")
{
}

// TestCase

TestCase* TestCase::createAsChild(TestGroup* parent, TestCaseType caseType, const char *name)
{
	return new TestCase(parent, caseType, name);
}

TestCase::TestCase (TestGroup* parent, TestCaseType caseType, const char* name)
	: TestNode		(parent, TESTNODETYPE_TEST_CASE, name)
	, m_caseType	(caseType)
{
}

TestCase::~TestCase (void)
{
}

// TestHierarchyBuilder helpers

void addChildGroupsToMap (std::map<std::string, TestGroup*>& groupMap, TestGroup* group)
{
	for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
	{
		TestNode* node = group->getChild(ndx);
		if (node->getNodeType() == TESTNODETYPE_GROUP)
		{
			TestGroup*	childGroup	= static_cast<TestGroup*>(node);
			std::string	fullPath;
			childGroup->getFullPath(fullPath);

			groupMap.insert(std::make_pair(fullPath, childGroup));
			addChildGroupsToMap(groupMap, childGroup);
		}
	}
}

// TestHierarchyBuilder

TestHierarchyBuilder::TestHierarchyBuilder (TestRoot* root)
	: m_root(root)
{
	addChildGroupsToMap(m_groupMap, root);
}

TestHierarchyBuilder::~TestHierarchyBuilder (void)
{
}

TestCase* TestHierarchyBuilder::createCase (const char* path, TestCaseType caseType)
{
	// \todo [2012-09-05 pyry] This can be done with less string manipulations.
	std::vector<std::string> components;
	splitPath(path, components);
	DE_ASSERT(!components.empty());

	// Create all parents if necessary.
	TestGroup*	curGroup		= m_root;
	std::string	curGroupPath;
	for (int ndx = 0; ndx < (int)components.size()-1; ndx++)
	{
		if (!curGroupPath.empty())
			curGroupPath += ".";
		curGroupPath += components[ndx];

		std::map<std::string, TestGroup*>::const_iterator groupPos = m_groupMap.find(curGroupPath);
		if (groupPos == m_groupMap.end())
		{
			TestGroup* newGroup = curGroup->createGroup(components[ndx].c_str());
			m_groupMap.insert(std::make_pair(curGroupPath, newGroup));
			curGroup = newGroup;
		}
		else
			curGroup = groupPos->second;
	}

	return curGroup->createCase(caseType, components.back().c_str());
}

// TestSet helpers

static void addNodeAndParents (std::set<const TestNode*>& nodeSet, const TestNode* node)
{
	while (node != DE_NULL)
	{
		nodeSet.insert(node);
		node = node->getParent();
	}
}

static void addChildren (std::set<const TestNode*>& nodeSet, const TestGroup* group)
{
	for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
	{
		const TestNode* child = group->getChild(ndx);
		nodeSet.insert(child);

		if (child->getNodeType() == TESTNODETYPE_GROUP)
			addChildren(nodeSet, static_cast<const TestGroup*>(child));
	}
}

static void removeChildren (std::set<const TestNode*>& nodeSet, const TestGroup* group)
{
	for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
	{
		const TestNode* child = group->getChild(ndx);
		nodeSet.erase(child);

		if (child->getNodeType() == TESTNODETYPE_GROUP)
			removeChildren(nodeSet, static_cast<const TestGroup*>(child));
	}
}

static bool hasChildrenInSet (const std::set<const TestNode*>& nodeSet, const TestGroup* group)
{
	for (int ndx = 0; ndx < group->getNumChildren(); ndx++)
	{
		if (nodeSet.find(group->getChild(ndx)) != nodeSet.end())
			return true;
	}
	return false;
}

static void removeEmptyGroups (std::set<const TestNode*>& nodeSet, const TestGroup* group)
{
	if (!hasChildrenInSet(nodeSet, group))
	{
		nodeSet.erase(group);
		if (group->getParent() != DE_NULL)
			removeEmptyGroups(nodeSet, group->getParent());
	}
}

// TestSet

void TestSet::add (const TestNode* node)
{
	if (node->getNodeType() == TESTNODETYPE_TEST_CASE)
		addCase(static_cast<const TestCase*>(node));
	else
	{
		XE_CHECK(node->getNodeType() == TESTNODETYPE_GROUP ||
				  node->getNodeType() == TESTNODETYPE_ROOT);
		addGroup(static_cast<const TestGroup*>(node));
	}
}

void TestSet::addCase (const TestCase* testCase)
{
	addNodeAndParents(m_set, testCase);
}

void TestSet::addGroup (const TestGroup* testGroup)
{
	addNodeAndParents(m_set, testGroup);
	addChildren(m_set, testGroup);
}

void TestSet::remove (const TestNode* node)
{
	if (node->getNodeType() == TESTNODETYPE_TEST_CASE)
		removeCase(static_cast<const TestCase*>(node));
	else
	{
		XE_CHECK(node->getNodeType() == TESTNODETYPE_GROUP ||
				  node->getNodeType() == TESTNODETYPE_ROOT);
		removeGroup(static_cast<const TestGroup*>(node));
	}
}

void TestSet::removeCase (const TestCase* testCase)
{
	if (m_set.find(testCase) != m_set.end())
	{
		m_set.erase(testCase);
		removeEmptyGroups(m_set, testCase->getParent());
	}
}

void TestSet::removeGroup (const TestGroup* testGroup)
{
	if (m_set.find(testGroup) != m_set.end())
	{
		m_set.erase(testGroup);
		removeChildren(m_set, testGroup);
		if (testGroup->getParent() != DE_NULL)
			removeEmptyGroups(m_set, testGroup->getParent());
	}
}

// ConstTestNodeIterator

ConstTestNodeIterator::ConstTestNodeIterator (const TestNode* root)
	: m_root(root)
{
}

ConstTestNodeIterator ConstTestNodeIterator::begin (const TestNode* root)
{
	ConstTestNodeIterator iter(root);
	iter.m_iterStack.push_back(GroupState(DE_NULL));
	return iter;
}

ConstTestNodeIterator ConstTestNodeIterator::end (const TestNode* root)
{
	DE_UNREF(root);
	return ConstTestNodeIterator(root);
}

ConstTestNodeIterator& ConstTestNodeIterator::operator++ (void)
{
	DE_ASSERT(!m_iterStack.empty());

	const TestNode*	curNode			= **this;
	TestNodeType	curNodeType		= curNode->getNodeType();

	if ((curNodeType == TESTNODETYPE_GROUP || curNodeType == TESTNODETYPE_ROOT) &&
		static_cast<const TestGroup*>(curNode)->getNumChildren() > 0)
	{
		m_iterStack.push_back(GroupState(static_cast<const TestGroup*>(curNode)));
	}
	else
	{
		for (;;)
		{
			const TestGroup*	group		= m_iterStack.back().group;
			int&				childNdx	= m_iterStack.back().childNdx;
			int					numChildren	= group ? group->getNumChildren() : 1;

			childNdx += 1;
			if (childNdx == numChildren)
			{
				m_iterStack.pop_back();
				if (m_iterStack.empty())
					break;
			}
			else
				break;
		}
	}

	return *this;
}

ConstTestNodeIterator ConstTestNodeIterator::operator++ (int)
{
	ConstTestNodeIterator copy(*this);
	++(*this);
	return copy;
}

const TestNode* ConstTestNodeIterator::operator* (void) const
{
	DE_ASSERT(!m_iterStack.empty());
	if (m_iterStack.size() == 1)
	{
		DE_ASSERT(m_iterStack[0].group == DE_NULL && m_iterStack[0].childNdx == 0);
		return m_root;
	}
	else
		return m_iterStack.back().group->getChild(m_iterStack.back().childNdx);
}

bool ConstTestNodeIterator::operator!= (const ConstTestNodeIterator& other) const
{
	return m_root != other.m_root || m_iterStack != other.m_iterStack;
}

} // xe
