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