/*-------------------------------------------------------------------------
 * 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 Batch result to JUnit report conversion tool.
 *//*--------------------------------------------------------------------*/

#include "xeTestLogParser.hpp"
#include "xeTestResultParser.hpp"
#include "xeXMLWriter.hpp"
#include "deFilePath.hpp"
#include "deString.h"
#include "deStringUtil.hpp"

#include <vector>
#include <string>
#include <map>
#include <cstdio>
#include <fstream>

using std::vector;
using std::string;
using std::map;

struct CommandLine
{
	CommandLine (void)
	{
	}

	std::string		batchResultFile;
	std::string		outputFile;
};

static void printHelp (const char* binName)
{
	printf("%s: [testlog] [output file]\n", binName);
}

static void parseCommandLine (CommandLine& cmdLine, int argc, const char* const* argv)
{
	if (argc != 3)
		throw xe::Error("Expected input and output paths");

	cmdLine.batchResultFile	= argv[argc-2];
	cmdLine.outputFile		= argv[argc-1];
}

static void parseBatchResult (xe::TestLogParser& parser, const char* filename)
{
	std::ifstream	in			(filename, std::ios_base::binary);
	deUint8			buf[2048];

	for (;;)
	{
		in.read((char*)&buf[0], sizeof(buf));
		int numRead = (int)in.gcount();

		if (numRead > 0)
			parser.parse(&buf[0], numRead);

		if (numRead < (int)sizeof(buf))
			break;
	}
}

class ResultToJUnitHandler : public xe::TestLogHandler
{
public:
	ResultToJUnitHandler (xe::xml::Writer& writer)
		: m_writer(writer)
	{
	}

	void setSessionInfo (const xe::SessionInfo&)
	{
	}

	xe::TestCaseResultPtr startTestCaseResult (const char* casePath)
	{
		return xe::TestCaseResultPtr(new xe::TestCaseResultData(casePath));
	}

	void testCaseResultUpdated (const xe::TestCaseResultPtr&)
	{
	}

	void testCaseResultComplete (const xe::TestCaseResultPtr& resultData)
	{
		using xe::xml::Writer;

		xe::TestCaseResult result;

		xe::parseTestCaseResultFromData(&m_resultParser, &result, *resultData.get());

		// Split group and case names.
		size_t			sepPos		= result.casePath.find_last_of('.');
		std::string		caseName	= result.casePath.substr(sepPos+1);
		std::string		groupName	= result.casePath.substr(0, sepPos);

		// Write result.
		m_writer << Writer::BeginElement("testcase")
				 << Writer::Attribute("name", caseName)
				 << Writer::Attribute("classname", groupName);

		if (result.statusCode != xe::TESTSTATUSCODE_PASS)
			m_writer << Writer::BeginElement("failure")
					 << Writer::Attribute("type", xe::getTestStatusCodeName(result.statusCode))
					 << result.statusDetails
					 << Writer::EndElement;

		m_writer << Writer::EndElement;
	}

private:
	xe::xml::Writer&		m_writer;
	xe::TestResultParser	m_resultParser;
};

static void batchResultToJUnitReport (const char* batchResultFilename, const char* dstFileName)
{
	std::ofstream				out			(dstFileName, std::ios_base::binary);
	xe::xml::Writer				writer		(out);
	ResultToJUnitHandler		handler		(writer);
	xe::TestLogParser			parser		(&handler);

	XE_CHECK(out.good());

	out << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";

	writer << xe::xml::Writer::BeginElement("testsuites")
		   << xe::xml::Writer::BeginElement("testsuite");

	// Parse and write individual cases
	parseBatchResult(parser, batchResultFilename);

	writer << xe::xml::Writer::EndElement << xe::xml::Writer::EndElement;
}

int main (int argc, const char* const* argv)
{
	CommandLine cmdLine;
	try
	{
		parseCommandLine(cmdLine, argc, argv);
	}
	catch (const std::exception&)
	{
		printHelp(argv[0]);
		return -1;
	}

	try
	{
		batchResultToJUnitReport(cmdLine.batchResultFile.c_str(), cmdLine.outputFile.c_str());
	}
	catch (const std::exception& e)
	{
		printf("%s\n", e.what());
		return -1;
	}

	return 0;
}
