#ifndef _TCUTESTHIERARCHYITERATOR_HPP
#define _TCUTESTHIERARCHYITERATOR_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 Test case hierarchy iterator.
 *//*--------------------------------------------------------------------*/

#include "tcuDefs.hpp"
#include "tcuTestContext.hpp"
#include "tcuTestCase.hpp"
#include "tcuTestPackage.hpp"

#include <vector>

namespace tcu
{

class CaseListFilter;

/*--------------------------------------------------------------------*//*!
 * \brief Test hierarchy inflater
 *
 * This interface is used by TestHierarchyIterator to materialize, and clean
 * up, test hierarchy on-demand while walking through it.
 *//*--------------------------------------------------------------------*/
class TestHierarchyInflater
{
public:
									TestHierarchyInflater	(void);

	virtual void					enterTestPackage		(TestPackage* testPackage, std::vector<TestNode*>& children) = 0;
	virtual void					leaveTestPackage		(TestPackage* testPackage) = 0;

	virtual void					enterGroupNode			(TestCaseGroup* testGroup, std::vector<TestNode*>& children) = 0;
	virtual void					leaveGroupNode			(TestCaseGroup* testGroup) = 0;

protected:
									~TestHierarchyInflater	(void);
};

// \todo [2015-02-26 pyry] Hierarchy traversal should not depend on TestContext
class DefaultHierarchyInflater : public TestHierarchyInflater
{
public:
									DefaultHierarchyInflater	(TestContext& testCtx);
									~DefaultHierarchyInflater	(void);

	virtual void					enterTestPackage			(TestPackage* testPackage, std::vector<TestNode*>& children);
	virtual void					leaveTestPackage			(TestPackage* testPackage);

	virtual void					enterGroupNode				(TestCaseGroup* testGroup, std::vector<TestNode*>& children);
	virtual void					leaveGroupNode				(TestCaseGroup* testGroup);

protected:
	TestContext&					m_testCtx;
};

/*--------------------------------------------------------------------*//*!
 * \brief Test hierarchy iterator
 *
 * Test hierarchy iterator allows walking test case hierarchy in depth-first
 * order. The walked sub-tree is limited by command line parameters.
 *
 * Iterator signals current state with getState(), which initally, and after
 * each increment (next()) may report one of the following:
 *
 * STATE_ENTER_NODE: A test node has been entered to for the first time.
 *   Node can be queried with getNode() and its full path with getNodePath().
 *   For group nodes the iterator will next enter first matching child node.
 *   For executable (test case) nodes STATE_LEAVE_NODE will always be reported
 *   immediately after entering that node.
 *
 * STATE_LEAVE_NODE: Iterator is leaving a node. In case of group nodes this
 *   means that all child nodes and their children have been processed. For
 *   executable nodes the iterator will either move on to the next sibling,
 *   or leave the parent group if the reported node was last child of that
 *   group.
 *
 * Root node is never reported, but instead iteration will start on first
 * matching test package node, if there is any.
 *
 * Test hierarchy is created on demand with help of TestHierarchyInflater.
 * Upon entering a group node, after STATE_ENTER_NODE has been signaled,
 * inflater is called to construct the list of child nodes for that group.
 * Upon exiting a group node, before STATE_LEAVE_NODE is called, inflater
 * is asked to clean up any resources by calling leaveGroupNode() or
 * leaveTestPackage() depending on the type of the node.
 *//*--------------------------------------------------------------------*/
class TestHierarchyIterator
{
public:
							TestHierarchyIterator	(TestPackageRoot& rootNode, TestHierarchyInflater& inflater, const CaseListFilter& caseListFilter);
							~TestHierarchyIterator	(void);

	enum State
	{
		STATE_ENTER_NODE = 0,
		STATE_LEAVE_NODE,
		STATE_FINISHED,

		STATE_LAST
	};

	State					getState				(void) const;

	TestNode*				getNode					(void) const;
	const std::string&		getNodePath				(void) const;

	void					next					(void);

private:
	struct NodeIter
	{
		enum State
		{
			NISTATE_INIT = 0,
			NISTATE_ENTER,
			NISTATE_TRAVERSE_CHILDREN,
			NISTATE_LEAVE,

			NISTATE_LAST
		};

		NodeIter (void)
			: node			(DE_NULL)
			, curChildNdx	(-1)
			, m_state		(NISTATE_LAST)
		{
		}

		NodeIter (TestNode* node_)
			: node			(node_)
			, curChildNdx	(-1)
			, m_state		(NISTATE_INIT)
		{
		}

		State getState (void) const
		{
			return m_state;
		}

		void setState (State newState)
		{
			switch (newState)
			{
				case NISTATE_TRAVERSE_CHILDREN:
					curChildNdx = -1;
					break;

				default:
					break;
			}

			m_state = newState;
		}

		TestNode*				node;
		std::vector<TestNode*>	children;
		int						curChildNdx;

	private:
		State					m_state;
	};

							TestHierarchyIterator	(const TestHierarchyIterator&);		// not allowed!
	TestHierarchyIterator&	operator=				(const TestHierarchyIterator&);		// not allowed!

	bool					matchFolderName			(const std::string& folderName) const;
	bool					matchCaseName			(const std::string& caseName) const;

	static std::string		buildNodePath			(const std::vector<NodeIter>& nodeStack);

	TestHierarchyInflater&	m_inflater;
	const CaseListFilter&	m_caseListFilter;

	// Current session state.
	std::vector<NodeIter>	m_sessionStack;
	std::string				m_nodePath;

	// Counter that increments by one for each bottom-level test group
	int						m_groupNumber;
};

} // tcu

#endif // _TCUTESTHIERARCHYITERATOR_HPP
