#ifndef _TCUTESTCASE_HPP
#define _TCUTESTCASE_HPP
/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * 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 Base class for a test case.
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "tcuTestContext.hpp"

#include <string>
#include <vector>

namespace tcu
{

enum TestNodeType
{
	NODETYPE_ROOT = 0,		//!< Root for all test packages.
	NODETYPE_PACKAGE,		//!< Test case package -- same as group, but is omitted from XML dump.
	NODETYPE_GROUP,			//!< Test case container -- cannot be executed.
	NODETYPE_SELF_VALIDATE,	//!< Self-validating test case -- can be executed
	NODETYPE_PERFORMANCE,	//!< Performace test case -- can be executed
	NODETYPE_CAPABILITY,	//!< Capability score case -- can be executed
	NODETYPE_ACCURACY		//!< Accuracy test case -- can be executed
};

enum TestNodeClass
{
	NODECLASS_GROUP = 0,	//!< Root or non-leaf in the test hierarchy tree
	NODECLASS_EXECUTABLE,	//!< Non-root leaf in the test hierarchy tree

	NODECLASS_LAST
};

enum TestRunnerType
{
	RUNNERTYPE_ANY		= 0u,
	RUNNERTYPE_NONE		= (1u << 0),
	RUNNERTYPE_AMBER	= (1u << 1)
};

inline TestNodeClass getTestNodeTypeClass (TestNodeType type)
{
	switch (type)
	{
		case NODETYPE_ROOT:				return NODECLASS_GROUP;
		case NODETYPE_PACKAGE:			return NODECLASS_GROUP;
		case NODETYPE_GROUP:			return NODECLASS_GROUP;
		case NODETYPE_SELF_VALIDATE:	return NODECLASS_EXECUTABLE;
		case NODETYPE_PERFORMANCE:		return NODECLASS_EXECUTABLE;
		case NODETYPE_CAPABILITY:		return NODECLASS_EXECUTABLE;
		case NODETYPE_ACCURACY:			return NODECLASS_EXECUTABLE;
		default:
			DE_ASSERT(false);
			return NODECLASS_LAST;
	}
}

inline bool isTestNodeTypeExecutable (TestNodeType type)
{
	return getTestNodeTypeClass(type) == NODECLASS_EXECUTABLE;
}

inline bool isValidTestCaseNameChar (char c)
{
	return de::inRange(c, 'a', 'z') ||
		   de::inRange(c, 'A', 'Z') ||
		   de::inRange(c, '0', '9') ||
		   c == '_' || c == '-';
}

/*--------------------------------------------------------------------*//*!
 * \brief Test case hierarchy node
 *
 * Test node forms the backbone of the test case hierarchy. All objects
 * in the hierarchy are derived from this class.
 *
 * Each test node has a type and all except the root node have name and
 * description. Root and test group nodes have a list of children.
 *
 * During test execution TestExecutor iterates the hierarchy. Upon entering
 * the node (both groups and test cases) init() is called. When exiting the
 * node deinit() is called respectively.
 *//*--------------------------------------------------------------------*/
class TestNode
{
public:
	enum IterateResult
	{
		STOP		= 0,
		CONTINUE	= 1
	};

	// Methods.
							TestNode		(TestContext& testCtx, TestNodeType nodeType, const char* name, const char* description);
							TestNode		(TestContext& testCtx, TestNodeType nodeType, const char* name, const char* description, const std::vector<TestNode*>& children);
	virtual					~TestNode		(void);

	TestNodeType			getNodeType		(void) const	{ return m_nodeType;			}
	TestContext&			getTestContext	(void) const	{ return m_testCtx;				}
	const char*				getName			(void) const	{ return m_name.c_str();		}
	const char*				getDescription	(void) const	{ return m_description.c_str(); }
	void					getChildren		(std::vector<TestNode*>& children);
	void					addChild		(TestNode* node);
	bool					empty			() const		{ return m_children.empty();	}

	virtual void			init			(void);
	virtual void			deinit			(void);
	virtual IterateResult	iterate			(void) = 0;
	virtual TestRunnerType	getRunnerType	(void) const	{ return RUNNERTYPE_NONE;		}

protected:
	TestContext&			m_testCtx;
	std::string				m_name;
	std::string				m_description;

private:
	const TestNodeType		m_nodeType;
	std::vector<TestNode*>	m_children;
};

/*--------------------------------------------------------------------*//*!
 * \brief Test case group node
 *
 * Test case group implementations must inherit this class. To save resources
 * during test execution the group must delay creation of any child groups
 * until init() is called.
 *
 * Default deinit() for test group will destroy all child nodes.
 *//*--------------------------------------------------------------------*/
class TestCaseGroup : public TestNode
{
public:
							TestCaseGroup	(TestContext& testCtx, const char* name, const char* description);
							TestCaseGroup	(TestContext& testCtx, const char* name, const char* description, const std::vector<TestNode*>& children);
	virtual					~TestCaseGroup	(void);

	virtual IterateResult	iterate			(void);
};

/*--------------------------------------------------------------------*//*!
 * \brief Test case class
 *
 * Test case implementations must inherit this class.
 *
 * Test case objects are usually constructed when TestExecutor enters parent
 * group. Allocating any non-parameter resources, especially target API objects
 * must be delayed to init().
 *
 * Upon entering the test case TestExecutor calls init(). If initialization
 * is successful (no exception is thrown) the executor will then call iterate()
 * until test case returns STOP. After that deinit() will be called.
 *
 * Before exiting the execution phase (i.e. at returning STOP from iterate())
 * the test case must set valid status code to test context (m_testCtx).
 *
 * Test case can also signal error condition by throwing an exception. In
 * that case the framework will set result code and details based on the
 * exception.
 *//*--------------------------------------------------------------------*/
class TestCase : public TestNode
{
public:
					TestCase			(TestContext& testCtx, const char* name, const char* description);
					TestCase			(TestContext& testCtx, TestNodeType nodeType, const char* name, const char* description);
	virtual			~TestCase			(void);
};

class TestStatus
{
public:
						TestStatus		(qpTestResult code, const std::string& description) : m_code(code), m_description(description) {}

	bool				isComplete		(void) const { return m_code != QP_TEST_RESULT_LAST;			}
	qpTestResult		getCode			(void) const { DE_ASSERT(isComplete()); return m_code;			}
	const std::string&	getDescription	(void) const { DE_ASSERT(isComplete()); return m_description;	}

	static TestStatus	pass			(const std::string& description)	{ return TestStatus(QP_TEST_RESULT_PASS,	description);	}
	static TestStatus	fail			(const std::string& description)	{ return TestStatus(QP_TEST_RESULT_FAIL,	description);	}
	static TestStatus	incomplete		(void)								{ return TestStatus(QP_TEST_RESULT_LAST,	"");			}

private:
	qpTestResult		m_code;
	std::string			m_description;
} DE_WARN_UNUSED_TYPE;

} // tcu

#endif // _TCUTESTCASE_HPP
