/*-------------------------------------------------------------------------
 * 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 iOS App Wrapper.
 *//*--------------------------------------------------------------------*/

#include "tcuIOSApp.h"
#include "tcuIOSPlatform.hh"
#include "tcuApp.hpp"
#include "tcuCommandLine.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuTestLog.hpp"
#include "tcuResource.hpp"
#include "deThread.hpp"
#include "deMutex.hpp"
#include "xsExecutionServer.hpp"
#include "xsTestProcess.hpp"
#include "xsPosixFileReader.hpp"
#include "deFilePath.hpp"
#include "deClock.h"
#include "deMemory.h"

#include <string>

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSBundle.h>
#import <Foundation/NSPathUtilities.h>

using std::string;

namespace
{

class TestThreadState
{
public:
	enum State
	{
		STATE_NOT_RUNNING	= 0,
		STATE_RUNNING,
		STATE_STOP_REQUESTED,

		STATE_LAST
	};

							TestThreadState			(void);
							~TestThreadState		(void);

	void					requestStart			(const char* cmdLine);
	void					requestStop				(void);
	State					getState				(void);

	void					testExecFinished		(void);

	const char*				getCommandLine			(void) const { return m_cmdLine.c_str(); }

private:
	de::Mutex				m_lock;

	State					m_state;
	std::string				m_cmdLine;
};

TestThreadState::TestThreadState (void)
	: m_state(STATE_NOT_RUNNING)
{
}

TestThreadState::~TestThreadState (void)
{
}

void TestThreadState::requestStart (const char* cmdLine)
{
	de::ScopedLock stateLock(m_lock);

	TCU_CHECK(m_state == STATE_NOT_RUNNING);

	m_cmdLine	= cmdLine;
	m_state		= STATE_RUNNING;
}

void TestThreadState::requestStop (void)
{
	de::ScopedLock stateLock(m_lock);

	if (m_state != STATE_NOT_RUNNING)
		m_state = STATE_STOP_REQUESTED;
}

void TestThreadState::testExecFinished (void)
{
	de::ScopedLock stateLock(m_lock);
	m_state = STATE_NOT_RUNNING;
}

TestThreadState::State TestThreadState::getState (void)
{
	de::ScopedLock stateLock(m_lock);
	return m_state;
}

class LocalTestProcess : public xs::TestProcess
{
public:
							LocalTestProcess		(TestThreadState& state, const char* logFileName);
							~LocalTestProcess		(void);

	void					start					(const char* name, const char* params, const char* workingDir, const char* caseList);
	void					terminate				(void);
	void					cleanup					(void);

	bool					isRunning				(void);
	int						getExitCode				(void) const { return 0; /* not available */ }

	int						readInfoLog				(deUint8* dst, int numBytes) { DE_UNREF(dst && numBytes); return 0; /* not supported */ }
	int						readTestLog				(deUint8* dst, int numBytes);

	const char*				getLogFileName			(void) const { return m_logFileName.c_str(); }

private:
	TestThreadState&		m_state;
	string					m_logFileName;
	xs::posix::FileReader	m_logReader;
	deUint64				m_processStartTime;
};

LocalTestProcess::LocalTestProcess (TestThreadState& state, const char* logFileName)
	: m_state				(state)
	, m_logFileName			(logFileName)
	, m_logReader			(xs::LOG_BUFFER_BLOCK_SIZE, xs::LOG_BUFFER_NUM_BLOCKS)
	, m_processStartTime	(0)
{
}

LocalTestProcess::~LocalTestProcess (void)
{
}

void LocalTestProcess::start (const char* name, const char* params, const char* workingDir, const char* caseList)
{
	DE_UNREF(name && workingDir);

	// Delete old log file.
	if (deFileExists(m_logFileName.c_str()))
		TCU_CHECK(deDeleteFile(m_logFileName.c_str()));

	string cmdLine = string("deqp");
	if (caseList && strlen(caseList) > 0)
		cmdLine += string(" --deqp-caselist=") + caseList;

	if (params && strlen(params) > 0)
		cmdLine += string(" ") + params;

	m_state.requestStart(cmdLine.c_str());
	m_processStartTime = deGetMicroseconds();
}

void LocalTestProcess::terminate (void)
{
	m_state.requestStop();
}

void LocalTestProcess::cleanup (void)
{
	if (isRunning())
	{
		m_state.requestStop();

		// Wait until stopped.
		while (isRunning())
			deSleep(50);
	}

	m_logReader.stop();
}

bool LocalTestProcess::isRunning (void)
{
	return m_state.getState() != TestThreadState::STATE_NOT_RUNNING;
}

int LocalTestProcess::readTestLog (deUint8* dst, int numBytes)
{
	if (!m_logReader.isRunning())
	{
		if (deGetMicroseconds() - m_processStartTime > xs::LOG_FILE_TIMEOUT*1000)
		{
			// Timeout, kill execution.
			terminate();
			return 0; // \todo [2013-08-13 pyry] Throw exception?
		}

		if (!deFileExists(m_logFileName.c_str()))
			return 0;

		// Start reader.
		m_logReader.start(m_logFileName.c_str());
	}

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

class ServerThread : public de::Thread
{
public:
						ServerThread		(xs::TestProcess* testProcess, int port);
						~ServerThread		(void);

	void				run					(void);
	void				stop				(void);

private:
	xs::ExecutionServer	m_server;
	bool				m_isRunning;
};

ServerThread::ServerThread (xs::TestProcess* testProcess, int port)
	: m_server		(testProcess, DE_SOCKETFAMILY_INET4, port, xs::ExecutionServer::RUNMODE_FOREVER)
	, m_isRunning	(false)
{
}

ServerThread::~ServerThread (void)
{
	stop();
}

void ServerThread::run (void)
{
	m_isRunning = true;
	m_server.runServer();
}

void ServerThread::stop (void)
{
	if (m_isRunning)
	{
		m_server.stopServer();
		join();
		m_isRunning = false;
	}
}

string getAppBundleDir (void)
{
	NSString*	dataPath	= [[NSBundle mainBundle] bundlePath];
	const char*	utf8Str		= [dataPath UTF8String];

	return string(utf8Str);
}

string getAppDocumentsDir (void)
{
	NSArray*	paths		= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
	NSString*	docPath		= [paths objectAtIndex:0];
	const char*	utf8Str		= [docPath UTF8String];

	return string(utf8Str);
}

} // anonymous

struct tcuIOSApp_s
{
public:
							tcuIOSApp_s		(void* view);
							~tcuIOSApp_s	(void);

	void					iterate			(void);

protected:
	void					createTestApp	(void);
	void					destroyTestApp	(void);

	TestThreadState			m_state;
	LocalTestProcess		m_testProcess;
	ServerThread			m_server;

	tcu::DirArchive			m_archive;
	tcu::ios::ScreenManager	m_screenManager;
	tcu::ios::Platform		m_platform;

	tcu::TestLog*			m_log;
	tcu::CommandLine*		m_cmdLine;
	tcu::App*				m_app;
};

tcuIOSApp_s::tcuIOSApp_s (void* view)
	: m_testProcess		(m_state, de::FilePath::join(getAppDocumentsDir(), "TestResults.qpa").getPath())
	, m_server			(&m_testProcess, 50016)
	, m_archive			(getAppBundleDir().c_str())
	, m_screenManager	((tcuEAGLView*)view)
	, m_platform		(&m_screenManager)
	, m_log				(DE_NULL)
	, m_cmdLine			(DE_NULL)
	, m_app				(DE_NULL)
{
	// Start server.
	m_server.start();
}

tcuIOSApp_s::~tcuIOSApp_s (void)
{
	m_server.stop();
	destroyTestApp();
}

void tcuIOSApp::createTestApp (void)
{
	DE_ASSERT(!m_app && !m_log && !m_cmdLine && !m_platform);

	try
	{
		m_log		= new tcu::TestLog(m_testProcess.getLogFileName());
		m_cmdLine	= new tcu::CommandLine(m_state.getCommandLine());
		m_app		= new tcu::App(m_platform, m_archive, *m_log, *m_cmdLine);
	}
	catch (const std::exception& e)
	{
		destroyTestApp();
		tcu::die("%s", e.what());
	}
}

void tcuIOSApp::destroyTestApp (void)
{
	delete m_app;
	delete m_cmdLine;
	delete m_log;
	m_app		= DE_NULL;
	m_cmdLine	= DE_NULL;
	m_log		= DE_NULL;
}

void tcuIOSApp::iterate (void)
{
	TestThreadState::State curState = m_state.getState();

	if (curState == TestThreadState::STATE_RUNNING)
	{
		if (!m_app)
			createTestApp();

		TCU_CHECK(m_app);

		if (!m_app->iterate())
		{
			destroyTestApp();
			m_state.testExecFinished();
		}
	}
	else if (curState == TestThreadState::STATE_STOP_REQUESTED)
	{
		destroyTestApp();
		m_state.testExecFinished();
	}
	// else wait until state has changed?
}

tcuIOSApp* tcuIOSApp_create (void* view)
{
	try
	{
		return new tcuIOSApp(view);
	}
	catch (const std::exception& e)
	{
		tcu::die("FATAL ERROR: %s", e.what());
		return DE_NULL;
	}
}

void tcuIOSApp_destroy (tcuIOSApp* app)
{
	delete app;
}

deBool tcuIOSApp_iterate (tcuIOSApp* app)
{
	try
	{
		app->iterate();
		return DE_TRUE;
	}
	catch (const std::exception& e)
	{
		tcu::print("FATAL ERROR: %s\n", e.what());
		return DE_FALSE;
	}
}
