/*-------------------------------------------------------------------------
 * drawElements Quality Program Execution Server
 * ---------------------------------------------
 *
 * 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 Test Execution Server.
 *//*--------------------------------------------------------------------*/

#include "xsExecutionServer.hpp"
#include "deClock.h"

#include <cstdio>

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

#if 1
#	define DBG_PRINT(X) printf X
#else
#	define DBG_PRINT(X)
#endif

namespace xs
{

inline bool MessageBuilder::isComplete (void) const
{
	if (m_buffer.size() < MESSAGE_HEADER_SIZE)
		return false;
	else
		return (int)m_buffer.size() == getMessageSize();
}

const deUint8* MessageBuilder::getMessageData (void) const
{
	return m_buffer.size() > MESSAGE_HEADER_SIZE ? &m_buffer[MESSAGE_HEADER_SIZE] : DE_NULL;
}

int MessageBuilder::getMessageDataSize (void) const
{
	DE_ASSERT(isComplete());
	return (int)m_buffer.size() - MESSAGE_HEADER_SIZE;
}

void MessageBuilder::read (ByteBuffer& src)
{
	// Try to get header.
	if (m_buffer.size() < MESSAGE_HEADER_SIZE)
	{
		while (m_buffer.size() < MESSAGE_HEADER_SIZE &&
			   src.getNumElements() > 0)
			m_buffer.push_back(src.popBack());

		DE_ASSERT(m_buffer.size() <= MESSAGE_HEADER_SIZE);

		if (m_buffer.size() == MESSAGE_HEADER_SIZE)
		{
			// Got whole header, parse it.
			Message::parseHeader(&m_buffer[0], (int)m_buffer.size(), m_messageType, m_messageSize);
		}
	}

	if (m_buffer.size() >= MESSAGE_HEADER_SIZE)
	{
		// We have header.
		int msgSize			= getMessageSize();
		int numBytesLeft	= msgSize - (int)m_buffer.size();
		int	numToRead		= de::min(src.getNumElements(), numBytesLeft);

		if (numToRead > 0)
		{
			int curBufPos = (int)m_buffer.size();
			m_buffer.resize(curBufPos+numToRead);
			src.popBack(&m_buffer[curBufPos], numToRead);
		}
	}
}

void MessageBuilder::clear (void)
{
	m_buffer.clear();
	m_messageType	= MESSAGETYPE_NONE;
	m_messageSize	= 0;
}

ExecutionServer::ExecutionServer (xs::TestProcess* testProcess, deSocketFamily family, int port, RunMode runMode)
	: TcpServer		(family, port)
	, m_testDriver	(testProcess)	
	, m_runMode		(runMode)
{
}

ExecutionServer::~ExecutionServer (void)
{
}

TestDriver* ExecutionServer::acquireTestDriver (void)
{
	if (!m_testDriverLock.tryLock())
		throw Error("Failed to acquire test driver");

	return &m_testDriver;
}

void ExecutionServer::releaseTestDriver (TestDriver* driver)
{
	DE_ASSERT(&m_testDriver == driver);
	DE_UNREF(driver);
	m_testDriverLock.unlock();
}

ConnectionHandler* ExecutionServer::createHandler (de::Socket* socket, const de::SocketAddress& clientAddress)
{
	printf("ExecutionServer: New connection from %s:%d\n", clientAddress.getHost(), clientAddress.getPort());
	return new ExecutionRequestHandler(this, socket);
}

void ExecutionServer::connectionDone (ConnectionHandler* handler)
{
	if (m_runMode == RUNMODE_SINGLE_EXEC)
		m_socket.close();

	TcpServer::connectionDone(handler);
}

ExecutionRequestHandler::ExecutionRequestHandler (ExecutionServer* server, de::Socket* socket)
	: ConnectionHandler	(server, socket)
	, m_execServer		(server)
	, m_testDriver		(DE_NULL)
	, m_bufferIn		(RECV_BUFFER_SIZE)
	, m_bufferOut		(SEND_BUFFER_SIZE)
	, m_run				(false)
	, m_sendRecvTmpBuf	(SEND_RECV_TMP_BUFFER_SIZE)
{
	// Set flags.
	m_socket->setFlags(DE_SOCKET_NONBLOCKING|DE_SOCKET_KEEPALIVE|DE_SOCKET_CLOSE_ON_EXEC);

	// Init protocol keepalives.
	initKeepAlives();
}

ExecutionRequestHandler::~ExecutionRequestHandler (void)
{
	if (m_testDriver)
		m_execServer->releaseTestDriver(m_testDriver);
}

void ExecutionRequestHandler::handle (void)
{
	DBG_PRINT(("ExecutionRequestHandler::handle()\n"));

	try
	{
		// Process execution session.
		processSession();
	}
	catch (const std::exception& e)
	{
		printf("ExecutionRequestHandler::run(): %s\n", e.what());
	}

	DBG_PRINT(("ExecutionRequestHandler::handle(): Done!\n"));

	// Release test driver.
	if (m_testDriver)
	{
		try
		{
			m_testDriver->reset();
		}
		catch (...)
		{
		}
		m_execServer->releaseTestDriver(m_testDriver);
		m_testDriver = DE_NULL;
	}

	// Close connection.
	if (m_socket->isConnected())
		m_socket->shutdown();
}

void ExecutionRequestHandler::acquireTestDriver (void)
{
	DE_ASSERT(!m_testDriver);

	// Try to acquire test driver - may fail.
	m_testDriver = m_execServer->acquireTestDriver();
	DE_ASSERT(m_testDriver);
	m_testDriver->reset();

}

void ExecutionRequestHandler::processSession (void)
{
	m_run = true;

	deUint64 lastIoTime = deGetMicroseconds();

	while (m_run)
	{
		bool anyIO = false;

		// Read from socket to buffer.
		anyIO = receive() || anyIO;

		// Send bytes in buffer.
		anyIO = send() || anyIO;

		// Process incoming data.
		if (m_bufferIn.getNumElements() > 0)
		{
			DE_ASSERT(!m_msgBuilder.isComplete());
			m_msgBuilder.read(m_bufferIn);
		}

		if (m_msgBuilder.isComplete())
		{
			// Process message.
			processMessage(m_msgBuilder.getMessageType(), m_msgBuilder.getMessageData(), m_msgBuilder.getMessageDataSize());

			m_msgBuilder.clear();
		}

		// Keepalives, anyone?
		pollKeepAlives();

		// Poll test driver for IO.
		if (m_testDriver)
			anyIO = getTestDriver()->poll(m_bufferOut) || anyIO;

		// If no IO happens in a reasonable amount of time, go to sleep.
		{
			deUint64 curTime = deGetMicroseconds();
			if (anyIO)
				lastIoTime = curTime;
			else if (curTime-lastIoTime > SERVER_IDLE_THRESHOLD*1000)
				deSleep(SERVER_IDLE_SLEEP); // Too long since last IO, sleep for a while.
			else
				deYield(); // Just give other threads chance to run.
		}
	}
}

void ExecutionRequestHandler::processMessage (MessageType type, const deUint8* data, int dataSize)
{
	switch (type)
	{
		case MESSAGETYPE_HELLO:
		{
			HelloMessage msg(data, dataSize);
			DBG_PRINT(("HelloMessage: version = %d\n", msg.version));
			if (msg.version != PROTOCOL_VERSION)
				throw ProtocolError("Unsupported protocol version");
			break;
		}

		case MESSAGETYPE_TEST:
		{
			TestMessage msg(data, dataSize);
			DBG_PRINT(("TestMessage: '%s'\n", msg.test.c_str()));
			break;
		}

		case MESSAGETYPE_KEEPALIVE:
		{
			KeepAliveMessage msg(data, dataSize);
			DBG_PRINT(("KeepAliveMessage\n"));
			keepAliveReceived();
			break;
		}

		case MESSAGETYPE_EXECUTE_BINARY:
		{
			ExecuteBinaryMessage msg(data, dataSize);
			DBG_PRINT(("ExecuteBinaryMessage: '%s', '%s', '%s', '%s'\n", msg.name.c_str(), msg.params.c_str(), msg.workDir.c_str(), msg.caseList.substr(0, 10).c_str()));
			getTestDriver()->startProcess(msg.name.c_str(), msg.params.c_str(), msg.workDir.c_str(), msg.caseList.c_str());
			keepAliveReceived(); // \todo [2011-10-11 pyry] Remove this once Candy is fixed.
			break;
		}

		case MESSAGETYPE_STOP_EXECUTION:
		{
			StopExecutionMessage msg(data, dataSize);
			DBG_PRINT(("StopExecutionMessage\n"));
			getTestDriver()->stopProcess();
			break;
		}

		default:
			throw ProtocolError("Unsupported message");
	}
}

void ExecutionRequestHandler::initKeepAlives (void)
{
	deUint64 curTime = deGetMicroseconds();
	m_lastKeepAliveSent		= curTime;
	m_lastKeepAliveReceived	= curTime;
}

void ExecutionRequestHandler::keepAliveReceived (void)
{
	m_lastKeepAliveReceived = deGetMicroseconds();
}

void ExecutionRequestHandler::pollKeepAlives (void)
{
	deUint64 curTime = deGetMicroseconds();

	// Check that we've got keepalives in timely fashion.
	if (curTime - m_lastKeepAliveReceived > KEEPALIVE_TIMEOUT*1000)
		throw ProtocolError("Keepalive timeout occurred");

	// Send some?
	if (curTime - m_lastKeepAliveSent > KEEPALIVE_SEND_INTERVAL*1000 &&
		m_bufferOut.getNumFree() >= MESSAGE_HEADER_SIZE)
	{
		vector<deUint8> buf;
		KeepAliveMessage().write(buf);
		m_bufferOut.pushFront(&buf[0], (int)buf.size());

		m_lastKeepAliveSent = deGetMicroseconds();
	}
}

bool ExecutionRequestHandler::receive (void)
{
	int maxLen = de::min<int>((int)m_sendRecvTmpBuf.size(), m_bufferIn.getNumFree());

	if (maxLen > 0)
	{
		int				numRecv;
		deSocketResult	result	= m_socket->receive(&m_sendRecvTmpBuf[0], maxLen, &numRecv);

		if (result == DE_SOCKETRESULT_SUCCESS)
		{
			DE_ASSERT(numRecv > 0);
			m_bufferIn.pushFront(&m_sendRecvTmpBuf[0], numRecv);
			return true;
		}
		else if (result == DE_SOCKETRESULT_CONNECTION_CLOSED)
		{
			m_run = false;
			return true;
		}
		else if (result == DE_SOCKETRESULT_WOULD_BLOCK)
			return false;
		else if (result == DE_SOCKETRESULT_CONNECTION_TERMINATED)
			throw ConnectionError("Connection terminated");
		else
			throw ConnectionError("receive() failed");
	}
	else
		return false;
}

bool ExecutionRequestHandler::send (void)
{
	int maxLen = de::min<int>((int)m_sendRecvTmpBuf.size(), m_bufferOut.getNumElements());

	if (maxLen > 0)
	{
		m_bufferOut.peekBack(&m_sendRecvTmpBuf[0], maxLen);

		int				numSent;
		deSocketResult	result	= m_socket->send(&m_sendRecvTmpBuf[0], maxLen, &numSent);

		if (result == DE_SOCKETRESULT_SUCCESS)
		{
			DE_ASSERT(numSent > 0);
			m_bufferOut.popBack(numSent);
			return true;
		}
		else if (result == DE_SOCKETRESULT_CONNECTION_CLOSED)
		{
			m_run = false;
			return true;
		}
		else if (result == DE_SOCKETRESULT_WOULD_BLOCK)
			return false;
		else if (result == DE_SOCKETRESULT_CONNECTION_TERMINATED)
			throw ConnectionError("Connection terminated");
		else
			throw ConnectionError("send() failed");
	}
	else
		return false;
}

} // xs
