/*-------------------------------------------------------------------------
 * 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 Render target info.
 *//*--------------------------------------------------------------------*/

#include "tcuApp.hpp"
#include "tcuPlatform.hpp"
#include "tcuTestContext.hpp"
#include "tcuTestSessionExecutor.hpp"
#include "tcuTestHierarchyUtil.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTestLog.hpp"

#include "qpInfo.h"
#include "qpDebugOut.h"

#include "deMath.h"

#include <iostream>

namespace tcu
{

using std::string;

/*--------------------------------------------------------------------*//*!
 *  Writes all packages found stdout without any
 *  separations. Recommended to be used with a single package
 *  only. It's possible to use test selectors for limiting the export
 *  to one package in a multipackage binary.
 *//*--------------------------------------------------------------------*/
static void writeCaselistsToStdout (TestPackageRoot& root, TestContext& testCtx)
{
	DefaultHierarchyInflater			inflater		(testCtx);
	de::MovePtr<const CaseListFilter>	caseListFilter	(testCtx.getCommandLine().createCaseListFilter(testCtx.getArchive()));
	TestHierarchyIterator				iter			(root, inflater, *caseListFilter);

	while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
	{
		iter.next();

		while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
		{
			if (iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE)
				std::cout << (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();
	}
}


/*--------------------------------------------------------------------*//*!
 * Verifies that amber capability requirements in the .amber files
 * match with capabilities defined on the CTS C code.
 *//*--------------------------------------------------------------------*/
static void verifyAmberCapabilityCoherency (TestPackageRoot& root, TestContext& testCtx)
{
	DefaultHierarchyInflater			inflater(testCtx);
	de::MovePtr<const CaseListFilter>	caseListFilter(testCtx.getCommandLine().createCaseListFilter(testCtx.getArchive()));
	TestHierarchyIterator				iter(root, inflater, *caseListFilter);
	int									count = 0;
	int									errorCount = 0;

	bool ok = true;

	while (iter.getState() != TestHierarchyIterator::STATE_FINISHED)
	{
		iter.next();

		while (iter.getNode()->getNodeType() != NODETYPE_PACKAGE)
		{
			if (iter.getState() == TestHierarchyIterator::STATE_ENTER_NODE &&
				isTestNodeTypeExecutable(iter.getNode()->getNodeType()))
			{
				std::cout << iter.getNodePath() << "\n";
				testCtx.getLog() << tcu::TestLog::Message << iter.getNodePath() << tcu::TestLog::EndMessage;
				if (!iter.getNode()->validateRequirements())
				{
					ok = false;
					errorCount++;
				}
				count++;
			}
			iter.next();
		}

		DE_ASSERT(iter.getState() == TestHierarchyIterator::STATE_LEAVE_NODE &&
			iter.getNode()->getNodeType() == NODETYPE_PACKAGE);
		iter.next();
	}
	std::cout << count << " amber tests, " << errorCount << " errors.\n";
	if (!ok)
		TCU_THROW(InternalError, "One or more CTS and Amber test requirements do not match; check log for details");

}

/*--------------------------------------------------------------------*//*!
 * \brief Construct test application
 *
 * If a fatal error occurs during initialization constructor will call
 * die() with debug information.
 *
 * \param platform Reference to platform implementation.
 *//*--------------------------------------------------------------------*/
App::App (Platform& platform, Archive& archive, TestLog& log, const CommandLine& cmdLine)
	: m_platform		(platform)
	, m_watchDog		(DE_NULL)
	, m_crashHandler	(DE_NULL)
	, m_crashed			(false)
	, m_testCtx			(DE_NULL)
	, m_testRoot		(DE_NULL)
	, m_testExecutor	(DE_NULL)
{
	if (!cmdLine.isSubProcess())
	{
		print("dEQP Core %s (0x%08x) starting..\n", qpGetReleaseName(), qpGetReleaseId());
		print("  target implementation = '%s'\n", qpGetTargetName());
	}

	if (!deSetRoundingMode(DE_ROUNDINGMODE_TO_NEAREST_EVEN))
		qpPrintf("WARNING: Failed to set floating-point rounding mode!\n");

	try
	{
		const RunMode	runMode	= cmdLine.getRunMode();

		// Initialize watchdog
		if (cmdLine.isWatchDogEnabled())
			TCU_CHECK_INTERNAL(m_watchDog = qpWatchDog_create(onWatchdogTimeout, this, WATCHDOG_TOTAL_TIME_LIMIT_SECS, WATCHDOG_INTERVAL_TIME_LIMIT_SECS));

		// Initialize crash handler.
		if (cmdLine.isCrashHandlingEnabled())
			TCU_CHECK_INTERNAL(m_crashHandler = qpCrashHandler_create(onCrash, this));

		// Create test context
		m_testCtx = new TestContext(m_platform, archive, log, cmdLine, m_watchDog);

		// Create root from registry
		m_testRoot = new TestPackageRoot(*m_testCtx, TestPackageRegistry::getSingleton());

		// \note No executor is created if runmode is not EXECUTE
		if (runMode == RUNMODE_EXECUTE)
			m_testExecutor = new TestSessionExecutor(*m_testRoot, *m_testCtx);
		else if (runMode == RUNMODE_DUMP_STDOUT_CASELIST)
			writeCaselistsToStdout(*m_testRoot, *m_testCtx);
		else if (runMode == RUNMODE_DUMP_XML_CASELIST)
			writeXmlCaselistsToFiles(*m_testRoot, *m_testCtx, cmdLine);
		else if (runMode == RUNMODE_DUMP_TEXT_CASELIST)
			writeTxtCaselistsToFiles(*m_testRoot, *m_testCtx, cmdLine);
		else if (runMode == RUNMODE_VERIFY_AMBER_COHERENCY)
			verifyAmberCapabilityCoherency(*m_testRoot, *m_testCtx);
		else
			DE_ASSERT(false);
	}
	catch (const std::exception& e)
	{
		cleanup();
		die("Failed to initialize dEQP: %s", e.what());
	}
}

App::~App (void)
{
	cleanup();
}

void App::cleanup (void)
{
	delete m_testExecutor;
	delete m_testRoot;
	delete m_testCtx;

	if (m_crashHandler)
		qpCrashHandler_destroy(m_crashHandler);

	if (m_watchDog)
		qpWatchDog_destroy(m_watchDog);
}

/*--------------------------------------------------------------------*//*!
 * \brief Step forward test execution
 * \return true if application should call iterate() again and false
 *         if test execution session is complete.
 *//*--------------------------------------------------------------------*/
bool App::iterate (void)
{
	if (!m_testExecutor)
	{
		DE_ASSERT(m_testCtx->getCommandLine().getRunMode() != RUNMODE_EXECUTE);
		return false;
	}

	// Poll platform events
	const bool platformOk = m_platform.processEvents();

	// Iterate a step.
	bool testExecOk = false;
	if (platformOk)
	{
		try
		{
			testExecOk = m_testExecutor->iterate();
		}
		catch (const std::exception& e)
		{
			die("%s", e.what());
		}
	}

	if ((!platformOk || !testExecOk) )
	{
		if (!m_testCtx->getCommandLine().isSubProcess())
		{
			if (!platformOk)
				print("\nABORTED!\n");
			else
				print("\nDONE!\n");
		}

		const RunMode runMode = m_testCtx->getCommandLine().getRunMode();
		if (runMode == RUNMODE_EXECUTE)
		{
			const TestRunStatus& result = m_testExecutor->getStatus();
			if(!m_testCtx->getCommandLine().isSubProcess())
			{
				// Report statistics.
				print("\nTest run totals:\n");
				print("  Passed:        %d/%d (%.1f%%)\n", result.numPassed,		result.numExecuted, (result.numExecuted > 0 ? (100.0f * (float)result.numPassed			/ (float)result.numExecuted) : 0.0f));
				print("  Failed:        %d/%d (%.1f%%)\n", result.numFailed,		result.numExecuted, (result.numExecuted > 0 ? (100.0f * (float)result.numFailed			/ (float)result.numExecuted) : 0.0f));
				print("  Not supported: %d/%d (%.1f%%)\n", result.numNotSupported,	result.numExecuted, (result.numExecuted > 0 ? (100.0f * (float)result.numNotSupported	/ (float)result.numExecuted) : 0.0f));
				print("  Warnings:      %d/%d (%.1f%%)\n", result.numWarnings,		result.numExecuted, (result.numExecuted > 0 ? (100.0f * (float)result.numWarnings		/ (float)result.numExecuted) : 0.0f));
				print("  Waived:        %d/%d (%.1f%%)\n", result.numWaived,		result.numExecuted, (result.numExecuted > 0 ? (100.0f * (float)result.numWaived			/ (float)result.numExecuted) : 0.0f));
				if (!result.isComplete)
					print("Test run was ABORTED!\n");
			}
			else
			{
				// subprocess sends test statisticts through qpa file, so that main process may read it
				// and add to global statistics ( search for #SubProcessStatus to see how it's done )
				std::ostringstream str;
				str << "\n#SubProcessStatus " <<
					result.numExecuted		<< " " <<
					result.numPassed		<< " " <<
					result.numFailed		<< " " <<
					result.numNotSupported	<< " " <<
					result.numWarnings		<< " " <<
					result.numWaived		<< "\n";
				m_testCtx->getLog().writeRaw(str.str().c_str());
			}
		}
	}

	return platformOk && testExecOk;
}

const TestRunStatus& App::getResult (void) const
{
	return m_testExecutor->getStatus();
}

void App::onWatchdogTimeout (qpWatchDog* watchDog, void* userPtr, qpTimeoutReason reason)
{
	DE_UNREF(watchDog);
	static_cast<App*>(userPtr)->onWatchdogTimeout(reason);
}

void App::onCrash (qpCrashHandler* crashHandler, void* userPtr)
{
	DE_UNREF(crashHandler);
	static_cast<App*>(userPtr)->onCrash();
}

void App::onWatchdogTimeout (qpTimeoutReason reason)
{
	if (!m_crashLock.tryLock() || m_crashed)
		return; // In crash handler already.

	m_crashed = true;

	m_testCtx->getLog().terminateCase(QP_TEST_RESULT_TIMEOUT);
	die("Watchdog timer timeout for %s", (reason == QP_TIMEOUT_REASON_INTERVAL_LIMIT ? "touch interval" : "total time"));
}

static void writeCrashToLog (void* userPtr, const char* infoString)
{
	// \note THIS IS CALLED BY SIGNAL HANDLER! CALLING MALLOC/FREE IS NOT ALLOWED!
	TestLog* log = static_cast<TestLog*>(userPtr);
	log->writeMessage(infoString);
}

static void writeCrashToConsole (void* userPtr, const char* infoString)
{
	// \note THIS IS CALLED BY SIGNAL HANDLER! CALLING MALLOC/FREE IS NOT ALLOWED!
	DE_UNREF(userPtr);
	qpPrint(infoString);
}

void App::onCrash (void)
{
	// \note THIS IS CALLED BY SIGNAL HANDLER! CALLING MALLOC/FREE IS NOT ALLOWED!

	if (!m_crashLock.tryLock() || m_crashed)
		return; // In crash handler already.

	m_crashed = true;

	bool isInCase = m_testExecutor ? m_testExecutor->isInTestCase() : false;

	if (isInCase)
	{
		qpCrashHandler_writeCrashInfo(m_crashHandler, writeCrashToLog, &m_testCtx->getLog());
		m_testCtx->getLog().terminateCase(QP_TEST_RESULT_CRASH);
	}
	else
		qpCrashHandler_writeCrashInfo(m_crashHandler, writeCrashToConsole, DE_NULL);

	die("Test program crashed");
}

} // tcu
