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

#include "tcuTestHierarchyUtil.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuCommandLine.hpp"

#include "qpXmlWriter.h"

#include <fstream>

namespace tcu
{

using std::string;

static const char* getNodeTypeName (TestNodeType nodeType)
{
	switch (nodeType)
	{
		case NODETYPE_SELF_VALIDATE:	return "SelfValidate";
		case NODETYPE_CAPABILITY:		return "Capability";
		case NODETYPE_ACCURACY:			return "Accuracy";
		case NODETYPE_PERFORMANCE:		return "Performance";
		case NODETYPE_GROUP:			return "TestGroup";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

// Utilities

static std::string makePackageFilename (const std::string& pattern, const std::string& packageName, const std::string& typeExtension)
{
	std::map<string, string> args;
	args["packageName"]		= packageName;
	args["typeExtension"]	= typeExtension;
	return StringTemplate(pattern).specialize(args);
}

static void writeXmlCaselist (TestHierarchyIterator& iter, qpXmlWriter* writer)
{
	DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
			  iter.getNode()->getNodeType() == NODETYPE_PACKAGE);

	{
		const TestNode* node		= iter.getNode();
		qpXmlAttribute	attribs[2];
		int				numAttribs	= 0;
		attribs[numAttribs++] = qpSetStringAttrib("PackageName", node->getName());
		attribs[numAttribs++] = qpSetStringAttrib("Description", node->getDescription());
		DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));

		if (!qpXmlWriter_startDocument(writer) ||
			!qpXmlWriter_startElement(writer, "TestCaseList", numAttribs, attribs))
			throw Exception("Failed to start XML document");
	}

	iter.next();

	while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
	{
		const TestNode* const	node		= iter.getNode();
		const TestNodeType		nodeType	= node->getNodeType();
		const bool				isEnter		= iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE;

		DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE ||
				  iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE);
		{
			if (isEnter)
			{
				const string	caseName	= node->getName();
				const string	description	= node->getDescription();
				qpXmlAttribute	attribs[3];
				int				numAttribs = 0;

				attribs[numAttribs++] = qpSetStringAttrib("Name",			caseName.c_str());
				attribs[numAttribs++] = qpSetStringAttrib("CaseType",		getNodeTypeName(nodeType));
				attribs[numAttribs++] = qpSetStringAttrib("Description",	description.c_str());
				DE_ASSERT(numAttribs <= DE_LENGTH_OF_ARRAY(attribs));

				if (!qpXmlWriter_startElement(writer, "TestCase", numAttribs, attribs))
					throw Exception("Writing to case list file failed");
			}
			else
			{
				if (!qpXmlWriter_endElement(writer, "TestCase"))
					throw tcu::Exception("Writing to case list file failed");
			}
		}

		iter.next();
	}

	// This could be done in catch, but the file is corrupt at that point anyways.
	if (!qpXmlWriter_endElement(writer, "TestCaseList") ||
		!qpXmlWriter_endDocument(writer))
		throw Exception("Failed to terminate XML document");
}

/*--------------------------------------------------------------------*//*!
 * \brief Export the test list of each package into a separate XML file.
 *//*--------------------------------------------------------------------*/
void writeXmlCaselistsToFiles (TestPackageRoot& root, TestContext& testCtx, const CommandLine& cmdLine)
{
	DefaultHierarchyInflater	inflater		(testCtx);
	TestHierarchyIterator		iter			(root, inflater, cmdLine);
	const char* const			filenamePattern = cmdLine.getCaseListExportFile();

	while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
	{
		const TestNode* node		= iter.getNode();
		const char*		pkgName		= node->getName();
		const string	filename	= makePackageFilename(filenamePattern, pkgName, "xml");

		DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
				  node->getNodeType() == NODETYPE_PACKAGE);

		FILE*			file	= DE_NULL;
		qpXmlWriter*	writer	= DE_NULL;

		try
		{
			file = fopen(filename.c_str(), "wb");
			if (!file)
				throw Exception("Failed to open " + filename);

			writer = qpXmlWriter_createFileWriter(file, DE_FALSE, DE_FALSE);
			if (!writer)
				throw Exception("XML writer creation failed");

			print("Writing test cases from '%s' to file '%s'..\n", pkgName, filename.c_str());

			writeXmlCaselist(iter, writer);

			qpXmlWriter_destroy(writer);
			writer = DE_NULL;

			fclose(file);
			file = DE_NULL;
		}
		catch (...)
		{
			if (writer)
				qpXmlWriter_destroy(writer);
			if (file)
				fclose(file);
			throw;
		}

		DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
				  iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
		iter.next();
	}
}

/*--------------------------------------------------------------------*//*!
 * \brief Export the test list of each package into a separate ascii file.
 *//*--------------------------------------------------------------------*/
void writeTxtCaselistsToFiles (TestPackageRoot& root, TestContext& testCtx, const CommandLine& cmdLine)
{
	DefaultHierarchyInflater	inflater		(testCtx);
	TestHierarchyIterator		iter			(root, inflater, cmdLine);
	const char* const			filenamePattern = cmdLine.getCaseListExportFile();

	while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
	{
		const TestNode* node		= iter.getNode();
		const char*		pkgName		= node->getName();
		const string	filename	= makePackageFilename(filenamePattern, pkgName, "txt");

		DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
				  node->getNodeType() == NODETYPE_PACKAGE);

		std::ofstream out(filename.c_str(), std::ios_base::binary);
		if (!out.is_open() || !out.good())
			throw Exception("Failed to open " + filename);

		print("Writing test cases from '%s' to file '%s'..\n", pkgName, filename.c_str());

		iter.next();

		while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
		{
			if (iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE)
				out << (isTestNodeTypeExecutable(iter.getNode()->getNodeType()) ? "TEST" : "GROUP") << ": " << iter.getNodePath() << "\n";
			iter.next();
		}

		DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
				  iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
		iter.next();
	}
}

} // tcu
