/*-------------------------------------------------------------------------
 * 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)
{
	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 (!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();

			// 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");
		}
	}

	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
