/*-------------------------------------------------------------------------
 * 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 TCP Server.
 *//*--------------------------------------------------------------------*/

#include "xsTcpServer.hpp"

#include <algorithm>
#include <iterator>
#include <cstdio>

namespace xs
{

TcpServer::TcpServer (deSocketFamily family, int port)
	: m_socket()
{
	de::SocketAddress address;
	address.setFamily(family);
	address.setPort(port);
	address.setType(DE_SOCKETTYPE_STREAM);
	address.setProtocol(DE_SOCKETPROTOCOL_TCP);

	m_socket.listen(address);
	m_socket.setFlags(DE_SOCKET_CLOSE_ON_EXEC);
}

void TcpServer::runServer (void)
{
	de::Socket*			clientSocket	= DE_NULL;
	de::SocketAddress	clientAddr;

	while ((clientSocket = m_socket.accept(clientAddr)) != DE_NULL)
	{
		ConnectionHandler* handler = DE_NULL;

		try
		{
			handler = createHandler(clientSocket, clientAddr);
		}
		catch (...)
		{
			delete clientSocket;
			throw;
		}

		try
		{
			addLiveConnection(handler);
		}
		catch (...)
		{
			delete handler;
			throw;
		}

		// Start handler.
		handler->start();

		// Perform connection list cleanup.
		deleteDoneConnections();
	}

	// One more cleanup pass.
	deleteDoneConnections();
}

void TcpServer::connectionDone (ConnectionHandler* handler)
{
	de::ScopedLock lock(m_connectionListLock);

	std::vector<ConnectionHandler*>::iterator liveListPos = std::find(m_liveConnections.begin(), m_liveConnections.end(), handler);
	DE_ASSERT(liveListPos != m_liveConnections.end());

	m_doneConnections.reserve(m_doneConnections.size()+1);
	m_liveConnections.erase(liveListPos);
	m_doneConnections.push_back(handler);
}

void TcpServer::addLiveConnection (ConnectionHandler* handler)
{
	de::ScopedLock lock(m_connectionListLock);
	m_liveConnections.push_back(handler);
}

void TcpServer::deleteDoneConnections (void)
{
	de::ScopedLock lock(m_connectionListLock);

	for (std::vector<ConnectionHandler*>::iterator i = m_doneConnections.begin(); i != m_doneConnections.end(); i++)
		delete *i;

	m_doneConnections.clear();
}

void TcpServer::stopServer (void)
{
	// Close socket. This should get accept() to return null.
	m_socket.close();
}

TcpServer::~TcpServer (void)
{
	try
	{
		std::vector<ConnectionHandler*> allConnections;

		if (m_connectionListLock.tryLock())
		{
			// \note [pyry] It is possible that cleanup actually fails.
			try
			{
				std::copy(m_liveConnections.begin(), m_liveConnections.end(), std::inserter(allConnections, allConnections.end()));
				std::copy(m_doneConnections.begin(), m_doneConnections.end(), std::inserter(allConnections, allConnections.end()));
			}
			catch (...)
			{
			}
			m_connectionListLock.unlock();
		}

		for (std::vector<ConnectionHandler*>::const_iterator i = allConnections.begin(); i != allConnections.end(); i++)
			delete *i;

		if (m_socket.getState() != DE_SOCKETSTATE_CLOSED)
			m_socket.close();
	}
	catch (...)
	{
		// Nada, we're at destructor.
	}
}

ConnectionHandler::~ConnectionHandler (void)
{
	delete m_socket;
}

void ConnectionHandler::run (void)
{
	try
	{
		handle();
	}
	catch (const std::exception& e)
	{
		printf("ConnectionHandler::run(): %s\n", e.what());
	}

	// Notify server that this connection is done.
	m_server->connectionDone(this);
}

} // xs
