/*-------------------------------------------------------------------------
 * 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 Android ExecServer.
 *//*--------------------------------------------------------------------*/

#include "tcuAndroidExecService.hpp"
#include "deFile.h"
#include "deClock.h"

#if 0
#	define DBG_PRINT(ARGS) print ARGS
#else
#	define DBG_PRINT(ARGS)
#endif

namespace tcu
{
namespace Android
{

static const char* LOG_FILE_NAME = "/sdcard/dEQP-log.qpa";

enum
{
	PROCESS_START_TIMEOUT	= 5000*1000,	//!< Timeout in usec.
	PROCESS_QUERY_INTERVAL	= 1000*1000		//!< Running query interval limit in usec.
};

static void checkJniException (JNIEnv* env, const char* file, int line)
{
	if (env->ExceptionOccurred())
	{
		env->ExceptionDescribe();
		env->ExceptionClear();
		throw InternalError("JNI Exception", DE_NULL, file, line);
	}
}

#define JNI_CHECK(EXPR) do { checkJniException(env, __FILE__, __LINE__); TCU_CHECK_INTERNAL(EXPR); } while (deGetFalse())

// TestProcess

TestProcess::TestProcess (JavaVM* vm, jobject context)
	: m_vm					(vm)
	, m_remoteCls			(0)
	, m_remote				(0)
	, m_start				(0)
	, m_kill				(0)
	, m_isRunning			(0)
	, m_launchTime			(0)
	, m_lastQueryTime		(0)
	, m_lastRunningStatus	(false)
	, m_logReader			(xs::LOG_BUFFER_BLOCK_SIZE, xs::LOG_BUFFER_NUM_BLOCKS)
{
	DBG_PRINT(("TestProcess::TestProcess(%p, %p)", vm, context));

	JNIEnv* env			= getCurrentThreadEnv();
	jobject	remote		= 0;
	jstring	logFileName	= 0;

	try
	{
		jclass		remoteCls	= 0;
		jmethodID	ctorId		= 0;

		remoteCls = env->FindClass("com/drawelements/deqp/testercore/RemoteAPI");
		JNI_CHECK(remoteCls);

		// Acquire global reference to RemoteAPI class.
		m_remoteCls = reinterpret_cast<jclass>(env->NewGlobalRef(remoteCls));
		JNI_CHECK(m_remoteCls);
		env->DeleteLocalRef(remoteCls);
		remoteCls = 0;

		ctorId = env->GetMethodID(m_remoteCls, "<init>", "(Landroid/content/Context;Ljava/lang/String;)V");
		JNI_CHECK(ctorId);

		logFileName = env->NewStringUTF(LOG_FILE_NAME);
		JNI_CHECK(logFileName);

		// Create RemoteAPI instance.
		remote = env->NewObject(m_remoteCls, ctorId, context, logFileName);
		JNI_CHECK(remote);

		env->DeleteLocalRef(logFileName);
		logFileName = 0;

		// Acquire global reference to remote.
		m_remote = env->NewGlobalRef(remote);
		JNI_CHECK(m_remote);
		env->DeleteLocalRef(remote);
		remote = 0;

		m_start	= env->GetMethodID(m_remoteCls, "start", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z");
		JNI_CHECK(m_start);

		m_kill = env->GetMethodID(m_remoteCls, "kill", "()Z");
		JNI_CHECK(m_kill);

		m_isRunning = env->GetMethodID(m_remoteCls, "isRunning", "()Z");
		JNI_CHECK(m_isRunning);
	}
	catch (...)
	{
		if (logFileName)
			env->DeleteLocalRef(logFileName);
		if (remote)
			env->DeleteLocalRef(remote);
		if (m_remoteCls)
			env->DeleteGlobalRef(reinterpret_cast<jobject>(m_remoteCls));
		if (m_remote)
			env->DeleteGlobalRef(m_remote);
		throw;
	}
}

TestProcess::~TestProcess (void)
{
	DBG_PRINT(("TestProcess::~TestProcess()"));

	try
	{
		JNIEnv* env = getCurrentThreadEnv();
		env->DeleteGlobalRef(m_remote);
		env->DeleteGlobalRef(m_remoteCls);
	}
	catch (...)
	{
	}
}

void TestProcess::start (const char* name, const char* params, const char* workingDir, const char* caseList)
{
	DBG_PRINT(("TestProcess::start(%s, %s, %s, ...)", name, params, workingDir));

	JNIEnv* env			= getCurrentThreadEnv();
	jstring	nameStr		= 0;
	jstring	paramsStr	= 0;
	jstring caseListStr	= 0;

	DE_UNREF(workingDir);

	// Remove old log file if such exists.
	if (deFileExists(LOG_FILE_NAME))
	{
		if (!deDeleteFile(LOG_FILE_NAME) || deFileExists(LOG_FILE_NAME))
			throw xs::TestProcessException(std::string("Failed to remove '") + LOG_FILE_NAME + "'");
	}

	try
	{
		nameStr = env->NewStringUTF(name);
		JNI_CHECK(nameStr);

		paramsStr = env->NewStringUTF(params);
		JNI_CHECK(paramsStr);

		caseListStr = env->NewStringUTF(caseList);
		JNI_CHECK(caseListStr);

		jboolean res = env->CallBooleanMethod(m_remote, m_start, nameStr, paramsStr, caseListStr);
		checkJniException(env, __FILE__, __LINE__);

		if (res == JNI_FALSE)
			throw xs::TestProcessException("Failed to launch activity");

		m_launchTime		= deGetMicroseconds();
		m_lastQueryTime		= m_launchTime;
		m_lastRunningStatus	= true;
	}
	catch (...)
	{
		if (nameStr)
			env->DeleteLocalRef(nameStr);
		if (paramsStr)
			env->DeleteLocalRef(paramsStr);
		if (caseListStr)
			env->DeleteLocalRef(caseListStr);
		throw;
	}

	env->DeleteLocalRef(nameStr);
	env->DeleteLocalRef(paramsStr);
	env->DeleteLocalRef(caseListStr);
}

void TestProcess::terminate (void)
{
	DBG_PRINT(("TestProcess::terminate()"));

	JNIEnv*		env		= getCurrentThreadEnv();
	jboolean	res		= env->CallBooleanMethod(m_remote, m_kill);
	checkJniException(env, __FILE__, __LINE__);
	DE_UNREF(res); // Failure to kill process is ignored.
}

void TestProcess::cleanup (void)
{
	DBG_PRINT(("TestProcess::cleanup()"));

	terminate();
	m_logReader.stop();
}

bool TestProcess::isRunning (void)
{
	deUint64 curTime = deGetMicroseconds();

	// On Android process launch is asynchronous so we don't want to poll for process until after some time.
	if (curTime-m_launchTime < PROCESS_START_TIMEOUT ||
		curTime-m_lastQueryTime < PROCESS_QUERY_INTERVAL)
		return m_lastRunningStatus;

	JNIEnv*		env		= getCurrentThreadEnv();
	jboolean	res		= env->CallBooleanMethod(m_remote, m_isRunning);
	checkJniException(env, __FILE__, __LINE__);

	DBG_PRINT(("TestProcess::isRunning(): %s", res == JNI_TRUE ? "true" : "false"));
	m_lastQueryTime		= curTime;
	m_lastRunningStatus	= res == JNI_TRUE;

	return m_lastRunningStatus;
}

JNIEnv* TestProcess::getCurrentThreadEnv (void)
{
	JNIEnv* env = DE_NULL;
	jint	ret	= m_vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);

	if (ret == JNI_OK)
		return env;
	else
		throw InternalError("GetEnv() failed");
}

int TestProcess::readTestLog (deUint8* dst, int numBytes)
{
	if (!m_logReader.isRunning())
	{
		if (deGetMicroseconds() - m_launchTime > xs::LOG_FILE_TIMEOUT*1000)
		{
			// Timeout, kill process.
			terminate();
			DBG_PRINT(("TestProcess:readTestLog(): Log file timeout occurred!"));
			return 0; // \todo [2013-08-13 pyry] Throw exception?
		}

		if (!deFileExists(LOG_FILE_NAME))
			return 0;

		// Start reader.
		m_logReader.start(LOG_FILE_NAME);
	}

	DE_ASSERT(m_logReader.isRunning());
	return m_logReader.read(dst, numBytes);
}

int	TestProcess::getExitCode (void) const
{
	return 0;
}

int TestProcess::readInfoLog (deUint8* dst, int numBytes)
{
	// \todo [2012-11-12 pyry] Read device log.
	DE_UNREF(dst && numBytes);
	return 0;
}

// ExecutionServer

ExecutionServer::ExecutionServer (JavaVM* vm, xs::TestProcess* testProcess, deSocketFamily family, int port, RunMode runMode)
	: xs::ExecutionServer	(testProcess, family, port, runMode)
	, m_vm					(vm)
{
}

xs::ConnectionHandler* ExecutionServer::createHandler (de::Socket* socket, const de::SocketAddress& clientAddress)
{
	DE_UNREF(clientAddress);
	return new ConnectionHandler(m_vm, this, socket);
}

// ConnectionHandler

ConnectionHandler::ConnectionHandler (JavaVM* vm, xs::ExecutionServer* server, de::Socket* socket)
	: xs::ExecutionRequestHandler	(server, socket)
	, m_vm							(vm)
{
}

void ConnectionHandler::run (void)
{
	JNIEnv* env = DE_NULL;
	if (m_vm->AttachCurrentThread(&env, DE_NULL) != 0)
	{
		print("AttachCurrentThread() failed");
		return;
	}

	xs::ExecutionRequestHandler::run();

	if (m_vm->DetachCurrentThread() != 0)
		print("DetachCurrentThread() failed");
}

// ServerThread

ServerThread::ServerThread (JavaVM* vm, xs::TestProcess* process, deSocketFamily family, int port)
	: m_server(vm, process, family, port, xs::ExecutionServer::RUNMODE_FOREVER)
{
}

void ServerThread::run (void)
{
	try
	{
		m_server.runServer();
	}
	catch (const std::exception& e)
	{
		die("ServerThread::run(): %s", e.what());
	}
}

void ServerThread::stop (void)
{
	m_server.stopServer();
	join();
}

// ExecService

ExecService::ExecService (JavaVM* vm, jobject context, int port, deSocketFamily family)
	: m_process		(vm, context)
	, m_thread		(vm, &m_process, family, port)
{
}

ExecService::~ExecService (void)
{
}

void ExecService::start (void)
{
	m_thread.start();
}

void ExecService::stop (void)
{
	m_thread.stop();
}

} // Android
} // tcu
