/*
 *
 *  Kepas - KDE Easy Publish and Share
 *
 *  Copyright (C) 2008  Tom Patzig <tpatzig@suse.de>
 *
 *  This file is part of kepas.
 *
 *  kepas 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.
 *
 *  kepas 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 kepas; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
*/

#include <servicelocator.h>
#include <KDebug>

ServiceLocator::ServiceLocator(QObject* parent)
{

	 checkRunStatus = false;

	 browser = new DNSSD::ServiceBrowser("_giver._tcp");
	 httpBrowser = new DNSSD::ServiceBrowser("_http._tcp");

	 receiver = new Receiver();

	 QHostInfo hostinfo;
	 hostname = hostinfo.localHostName();
	 
	 char* user = getenv("USER");
	 username = user;

	 receiver->setTargetPath(getenv("HOME"));

	 kDebug() << "hostname" << hostname;
	 kDebug() << "user" << username;

         server = 0;
         service = 0;

//	 checkBrowse();
}


ServiceLocator::~ServiceLocator()
{
	kDebug() << "deleting avahiService";

	if (receiver)
		delete receiver;
	if (service)
		delete service;
	if (browser)
		delete browser;
	if (httpBrowser)
		delete httpBrowser;
	if (server)
		delete server;
}

void ServiceLocator::startService()
{

    	 server = new QTcpServer(this);
	 server->listen(QHostAddress::Any,0);
	 connect(server,SIGNAL(newConnection()),this, SLOT(slotNewConnection()));
	
	 kDebug() << "user " << username;

	 kDebug() << "homedir " << receiver->getTargetPath();
	 kDebug() << "serverPort " << server->serverPort();
	 
//	 QMap<QString,QByteArray> serviceID;
//	 QByteArray dataID;
//	 dataID.append(QString(username + "@" + hostname + ":" + QString::number(server->serverPort())));

	 QByteArray dataName;
	 dataName.append(username.toLatin1());

	 QByteArray dataHostName;
	 dataHostName.append(hostname.toLatin1());

	 QByteArray dataPort;
	 dataPort.append(QString::number(server->serverPort()).toLatin1());


	 serviceID["User Name"] = dataName;
	 serviceID["Machine Name"] = dataHostName;
//	 serviceID["id"] = dataID;
	 serviceID["port"] = dataPort;
	 
	 service = new DNSSD::PublicService("kepas on " + username + "@" + hostname,"_giver._tcp",server->serverPort(),"local."); 
	 service->setTextData(serviceID);
	 
	 //we need to publish asynchron, otherwise plasma will crash on login, when loading kepas!!
	 connect(service,SIGNAL(published(bool)),this,SLOT(wasPublished(bool)));
	 service->publishAsync();


}

void ServiceLocator::wasPublished(bool isOK)
{
	 if (isOK)
		kDebug() << "Service published on port " << server->serverPort();
	 else
		kDebug() << "Service not published";	
}

bool ServiceLocator::restartPublish()
{
	service->stop();

	QByteArray dataName;
        dataName.append(username.toLatin1());
	serviceID["User Name"] = dataName;
	
	service->setServiceName("kepas on " + username + "@" + hostname);
	
	service->setTextData(serviceID);
	return (service->publish());

}


void ServiceLocator::browse()
{
	 connect(browser,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),this,SLOT(addService(DNSSD::RemoteService::Ptr)));
	 connect(browser,SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)),this,SLOT(delService(DNSSD::RemoteService::Ptr)));
	 browser->startBrowse();
}

void ServiceLocator::httpBrowse()
{
	 connect(httpBrowser,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),this,SLOT(addHttpService(DNSSD::RemoteService::Ptr)));
	 connect(httpBrowser,SIGNAL(serviceRemoved(DNSSD::RemoteService::Ptr)),this,SLOT(delHttpService(DNSSD::RemoteService::Ptr)));
	 httpBrowser->startBrowse();
}

void ServiceLocator::checkBrowse()
{
	 connect(browser,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),this,SLOT(addService(DNSSD::RemoteService::Ptr)));
	 connect(browser,SIGNAL(finished()),this,SLOT(checkBrowseFinished()));
	 browser->startBrowse();
}

void ServiceLocator::checkBrowseFinished()
{

	kDebug() << "browse finished";
	if (checkRunStatus)
		emit serviceRuns();
	else {
		checkRunStatus = false;
	 	disconnect(browser,SIGNAL(serviceAdded(DNSSD::RemoteService::Ptr)),this,SLOT(addService(DNSSD::RemoteService::Ptr)));
	 	disconnect(browser,SIGNAL(finished()),this,SLOT(checkBrowseFinished()));
		startService();
	}
}


void ServiceLocator::addService(DNSSD::RemoteService::Ptr srv)
{
	 srv->resolve();
	 kDebug() << "Service found " << srv->serviceName();
	 kDebug() << "Service Host " << srv->hostName();
	 QMap<QString, QByteArray> map = srv->textData();
/*
	 if (map["id"].count() == 0) {
		QByteArray tmp;
		tmp.append(QString(srv->hostName() + ":" + QString::number(srv->port())).toLatin1());
		map["id"] = tmp;
	 }
*/
	 if (map["port"].count() == 0) {
		QByteArray tmp;
		tmp.append(QString::number(srv->port()).toLatin1());
		map["port"] = tmp;
	 }
	 if (map["SN"].count() == 0) {
		QByteArray tmp;
		tmp.append(srv->serviceName().toLatin1());
		map["SN"] = tmp;
	 }

	 if (map["llname"].count() == 0) {
		QByteArray tmp;
		tmp.append(srv->hostName().toLatin1());
		map["llname"] = tmp;
	 }

/*	 
	 if (map["Machine Name"] == hostname) {
		checkRunStatus = true;
		kDebug() << "Service already running!";
	 
	 }  else
*/
 	emit addBuddy(map);

}

void ServiceLocator::addHttpService(DNSSD::RemoteService::Ptr srv)
{	 srv->resolve();
	 kDebug() << "Http Service found " << srv->hostName();
	 emit httpFound(srv->serviceName(),QString(srv->hostName() + ":" + QString::number(srv->port())));
}

void ServiceLocator::delHttpService(DNSSD::RemoteService::Ptr srv)
{
	 kDebug() << "Http Service removed " << srv->serviceName();
	 emit httpRemoved(srv->serviceName());
}


void ServiceLocator::delService(DNSSD::RemoteService::Ptr srv)
{
	 kDebug() << "Service removed " << srv->serviceName();
	 emit delBuddy(srv->serviceName());
}


void ServiceLocator::slotNewConnection()
{
	
	kDebug() << "new TCP connection" ;

	socket = server->nextPendingConnection();


	kDebug() << socket->peerPort();
	kDebug() << socket->peerAddress();
	

	receiver->defReqType(socket);

}

void ServiceLocator::launchReceiver()
{
	receiver->defReqType(socket);
}

void ServiceLocator::setUserName(QString name)
{
	username = name;

}

QString ServiceLocator::getUserName()
{
	return username;
}
