/***************************************************************************
 *   Copyright (C) 2004 by Christoph Thielecke                             *
 *   crissi99@gmx.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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "toolinfo.h"
#include <qfile.h>
#include <iostream>
#include <klocale.h>
#include <kstandarddirs.h>
#include <kmessagebox.h>
#include "toolinfo.moc"

ToolInfo::ToolInfo(const QString &Name)
{
	this->Name = Name;
	/*
		if (!PathToExec.isEmpty())
			SearchPathList.append(PathToExec);*/
	// 	if (GlobalConfig->KvpncDebugLevel > 0)
// 	std::cout << "Checking for: " << Name.ascii() << std::endl;

	SearchPathList.append("/bin");
	SearchPathList.append("/sbin");
	SearchPathList.append("/usr/bin");
	SearchPathList.append("/usr/sbin");
	SearchPathList.append("/usr/local/bin");
	SearchPathList.append("/usr/local/sbin");
	SearchPathList.append("/root/bin");
	SearchPathList.append(QString (QString(getenv("$HOME"))+"/bin"));

	Version=i18n("No info");
}

bool ToolInfo::collectToolInfo()
{
	bool success=false;
	PathToExec=KStandardDirs::findExe(Name);

	if (PathToExec.isEmpty())
		PathToExec=KStandardDirs::findExe(Name, QString(QString(getenv("$HOME"))+"/bin"));

	if (PathToExec.isEmpty())
		PathToExec=KStandardDirs::findExe(Name, QString("/sbin"));

	if (PathToExec.isEmpty())
		PathToExec=KStandardDirs::findExe(Name, QString("/usr/sbin"));

	if (!PathToExec.isEmpty())
	{

		CollectToolInfoProcess = new QProcess(this);
		CollectToolInfoProcess->clearArguments();
		connect( CollectToolInfoProcess, SIGNAL( readyReadStdout() ), this, SLOT( readStdOutCollectToolInfo() ) );
		connect( CollectToolInfoProcess, SIGNAL( readyReadStderr() ), this, SLOT( readStdErrCollectToolInfo() ) );
		//connect( CollectToolInfoProcess, SIGNAL( processExited () ), this, SLOT(processFinished()  ) );
		bool run=true;

		//FIXME how it could be better?
		CollectToolInfoProcess->addArgument(PathToExec);
		if (Name == "vpnc")
			CollectToolInfoProcess->addArgument("--version");
		else	if (Name == "ipsec")
			CollectToolInfoProcess->addArgument("--version");
		else	if (Name == "racoon")
		{
			// we need to do some stupid hack...
			// /usr/sbin/racoon -> /usr/sbin/setkey
			CollectToolInfoProcess->clearArguments();
			CollectToolInfoProcess->addArgument(QString(PathToExec.left(PathToExec.length()-6)+"setkey"));
			CollectToolInfoProcess->addArgument("-V");
		}
		else	if (Name == "setkey")
			CollectToolInfoProcess->addArgument("-V");
		else	if (Name == "openvpn")
			CollectToolInfoProcess->addArgument("--version");
		else	if (Name == "openssl")
			CollectToolInfoProcess->addArgument("version");
		else	if (Name == "pppd")
			CollectToolInfoProcess->addArgument("--version");
		else	if (Name == "iptables")
			CollectToolInfoProcess->addArgument("-V");
		else	if (Name == "kill")
		{
// 			run=false;
// 			success=true;
			CollectToolInfoProcess->addArgument("-V");
		}
		else	if (Name == "killall")
			CollectToolInfoProcess->addArgument("-V");
		else	if (Name == "ping")
			CollectToolInfoProcess->addArgument("-V");
		else	if (Name == "ip")
			CollectToolInfoProcess->addArgument("-V");
		else	if (Name == "ifconfig")
			CollectToolInfoProcess->addArgument("-V");
		else	if (Name == "route")
			CollectToolInfoProcess->addArgument("-V");
		else	if (Name == "pptp")
			;
		else
		{
			std::cout << "Invalid tool (" << Name.ascii() <<")!" << std::endl;
			run=false;
			success=false;
		}

		collectRunning=false;

		if (run )
		{

			if ( !PathToExec.isEmpty() && !CollectToolInfoProcess->start() )
			{
				//std::cerr << i18n("Unable to start collectToolInfo process (%1)!").arg(Name) << std::endl;

				//delete CollectToolInfoProcess;
				collectRunning=false;
				success=false;
			}
			else
			{
				collectRunning=true;
				while(CollectToolInfoProcess->isRunning() && collectRunning)
				{}

				//KMessageBox::information(0,QString("Name: "+Name+", Path: "+PathToExec+", Version: "+Version),"aaa");
				// 		disconnect( CollectToolInfoProcess, SIGNAL( readyReadStdout() ), this, SLOT( readStdOutCollectToolInfo() ) );
				// 		disconnect( CollectToolInfoProcess, SIGNAL( readyReadStderr() ), this, SLOT( readStdErrCollectToolInfo() ) );
				// 		delete CollectToolInfoProcess;
				success=true;
			}
		}

		disconnect( CollectToolInfoProcess, SIGNAL( readyReadStdout() ), this, SLOT( readStdOutCollectToolInfo() ) );
		disconnect( CollectToolInfoProcess, SIGNAL( readyReadStderr() ), this, SLOT( readStdErrCollectToolInfo() ) );


		//std::cout << "Name: " << Name << ", Path: " << PathToExec << ", Version: " << Version << std::endl;
	}
	return success;
}


void ToolInfo::readStdOutCollectToolInfo()
{
	while (CollectToolInfoProcess->canReadLineStdout())
	{
		QString msg = QString( CollectToolInfoProcess->readLineStdout() );
		//	QString msg = QString( CollectToolInfoProcess->readStdout() );
// 		std::cout << "Checking for: " << Name.ascii() << std::endl;
// 		std::cout << "stdout collectToolInfo: " << msg.ascii() <<std::endl;

		//FIXME how it could be better?
		if (Name == "vpnc")
		{
			if ( msg.find( "version", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',2,2);
			}
		}
		else	if (Name == "ipsec")
		{
			if ( msg.find( "wan", 0, FALSE ) > -1 )
			{
// 				std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',1,2);
			}
		}
		else	if (Name == "racoon")
		{

			// we need to do some stupid hack...
			// /usr/sbin/racoon -> /usr/sbin/setkey
			CollectToolInfoProcess->addArgument(QString(PathToExec.left(PathToExec.length()-6)+"setkey"));
			if ( msg.find( "ipsec-tools", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',3,3);
			}
		}
		else	if (Name == "setkey")
		{
			if ( msg.find( "ipsec-tools", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',3,3);
			}
		}
		else	if (Name == "openvpn")
		{
			if ( msg.find( "built", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',1,1);
			}
		}
		else	if (Name == "openssl")
		{
			if ( msg.find( "OpenSSL", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',1,1);
			}
		}
		else	if (Name == "pppd")
		{
			if ( msg.find( "version", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',2,2);
			}
		}
		else	if (Name == "iptables")
		{
			if ( msg.find( "iptables", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',1,1);
			}
		}
		else	if (Name == "ping")
		{
			if ( msg.find( "ping", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',2,2);
			}
		}
		else	if (Name == "ip")
		{
			if ( msg.find( "ip", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',2,2);
			}
		}
		else	if (Name == "kill")
		{
			if ( msg.find( "kill", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',3,3).section(')',0,0);
			}
		}
		else
		{
			;
		}
	}
	collectRunning=false;
}

void ToolInfo::readStdErrCollectToolInfo()
{
	while (CollectToolInfoProcess->canReadLineStderr())
	{
		QString msg = QString( CollectToolInfoProcess->readLineStderr() );
// 				std::cout << "Checking for: " << Name.ascii() << std::endl;
// 		std::cout << "stderr collectToolInfo: " << msg.ascii() <<std::endl;

		if (Name == "pppd")
		{
			if ( msg.find( "version", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',2,2);
			}
		}
		else	if (Name == "killall")
		{
			if ( msg.find( "killall", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',2,2);
			}
		}
		else	if (Name == "ifconfig")
		{
			//KMessageBox::information(0,QString("Name: "+Name+", Path: "+PathToExec+", Version: "+Version),"aaa");
			if ( msg.find( "ifconfig", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',1,1);
			}
		}
		else	if (Name == "route")
		{
			if ( msg.find( "route", 0, FALSE ) > -1 )
			{
				//std::cout << "stdout collectToolInfo: " << msg << std::endl;
				Version = msg.section(' ',1,1);
			}
		}
		else	if (Name == "pptp")
		{
			if ( msg.find( "pptp version", 0, FALSE ) > -1 )
			{
//				std::cout << "stdout collectToolInfo: " << msg.ascii() << std::endl;
				Version = msg.section(' ',2,2).section(')',0,0);
			}
		}
	}
}


void ToolInfo::processFinished()
{
	collectRunning=false;
}

void ToolInfo::addSearchPath(const QString& )
{
	/*
	std::cout << "Path added: " << path << std::endl;
	if (!path.isEmpty())
		SearchPathList.insert(SearchPathList.begin(), QString(path));
	else
	*/
	return;
}
