/***************************************************************************
 *   Copyright (C) 2005 by xavier helluy   *
 *   xavier.helluy@web.de   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.             *
 ***************************************************************************/

#include <kdebug.h>

#include "server.h"
#include "serverclient.h"

#include <kresolver.h> 
#include <sys/socket.h>
#include <sys/stat.h>
#include <qfile.h>
#include <kde_file.h>   //??




Server::Server(const QCString & socketPath) : socketPath(socketPath)
{	
}

Server::~Server()
{
	m_socket->close();
	deleteSocket(socketPath);
}

int Server::deleteSocket(const QCString & socketPath)
{
	kdDebug() << "Server::deleteSocket" << socketPath << endl;

	QFile file( socketPath );
		
	if (!file.exists())
	{
		kdDebug() << "Server::deleteSocket. No socket file found to be removed" << endl;
		return 0;
	}
	else
	{
		KDE_struct_stat buff;
		//struct stat buff;
		if ( KDE_stat( QFile::encodeName(socketPath), &buff ) != -1 )
		{
			if ( S_ISSOCK( buff.st_mode ) )
			{
				file.remove();
				if (!file.exists())
				{
					kdWarning() << "Server::deleteSocket. Found a Socket and  Removed it" << endl; 
					return -1;
				}
				else
				{
					kdError() << "Server::deleteSocket. Found a Socket and could not removed it" << endl; 
					return -2;
				}
			}
			else
			{
				kdError() << "Server::deleteSocket. URI point to a file, not a socket !!!" << socketPath << endl;
				return -3;
			}
			
		}
		else
		{
			// ??????? where am I here ??????
			kdError() << "Server::deleteSocket. Unknown error" << endl;
			return -4;
		}
	}
	kdDebug() << "Server::deleteSocket. Bye!" << endl;
	return -3;
}

bool Server::init()
{
	//assumes it can create the socket
	KNetwork::KUnixSocketAddress  AddrSocket(socketPath);
	//FIXME: use KResolver enums instead of sys/socket enums
	const KNetwork::KResolverEntry   Socket(AddrSocket ,SOCK_STREAM , PF_UNIX , "unknown" ,(QCString) "unknown" ); 
// 	m_dispatcherSocket = new KNetwork::KSocketDevice();
// 	m_dispatcherSocket->create(Socket);
	
// 	m_dispatcherSocket->setBlocking(TRUE);
	
	
	m_dispatcherSocket  = new KNetwork::KServerSocket();
	m_dispatcherSocket->setAcceptBuffered(false);
	m_dispatcherSocket->setBlocking(TRUE);
	kdDebug() << "Server::init() CONNECT BAD" << endl;

	if (! m_dispatcherSocket->bind(Socket) )
	{
		kdDebug() << "Server::init() CONNECT BAD" << endl;
		return FALSE;
	}
	return TRUE;
}
void Server::listenAndAccept()
{
	int MaxConn = 1; //only one peer2peer connection
	if (! m_dispatcherSocket->listen(MaxConn) )
	{
		kdDebug() << "Server::listenAndAccept. Listen is BAD" << endl;
	}
	
	m_socket =  static_cast<KNetwork::KStreamSocket*> (m_dispatcherSocket->accept());
	//used to be m_socket = (m_dispatcherSocket->accept(); where both were SocketDevice

	if (! m_socket)
	{
		kdDebug() << "Server::listenAndAccept. Accept: BAD" << endl;
	}
	//close listening socket 
	m_dispatcherSocket->close();	
	
	if (!m_socket->blocking())
	{		
		kdDebug() << "Server::listenAndAccept _NOT Blocking_" << endl;
	}

	//make sure client is here
	sendSignal((QString) "Are you ready ?" );

	if ( ! getSignal( (QString) "I am ready."))
	{
		kdDebug() << "Server::listenAndAccept. Server got Bad Confirmation" << endl;
	}
	kdDebug() << "Server::listenAndAccept. Server got Good Confirmation" << endl;
	
	sendSignal( (QString) "OK") ;  //the client sends data to the server.
	//that's why the server has to tell ok. The client wait for the ok and sends data
}
