//
// C++ Implementation: runcommandinxterm
//
// Description: 
//
//
// Author: Benjamin Mesing <bensmail@gmx.net>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//

#include <algorithm>
#include <functional>

#include <unistd.h>		// for getuid and geteuids
#include <sys/types.h>	//

#include <QFileInfo>
#include <qstring.h>
#include <qprocess.h>

// NApplication
#include "runcommandinxterm.h"
#include "gainroot.h"

// NException
#include "exception.h"

#include <helpers.h>


namespace NApplication {



RunCommandInXterm::RunCommandInXterm()
{
	_pProcess=0;
}


RunCommandInXterm::~RunCommandInXterm()
{
	delete _pProcess;
}


void RunCommandInXterm::addArgument(const QString& arg)
{
	_arguments.push_back(arg);
}


bool RunCommandInXterm::start(bool root)
{
	_pProcess = new QProcess(0);
	QString argumentString = _arguments.join(" ");

	QString terminalEmulatorFullPath = "/usr/bin/uxterm";
	QFileInfo terminalEmulator(terminalEmulatorFullPath);
	if (!terminalEmulator.isExecutable())
		throw NException::RuntimeException(toString(terminalEmulatorFullPath) + string(" is not executable/available, "
		"probably there is no teminal emulator installed"));
	
	QFileInfo command(_arguments[0]);
	if (!command.isExecutable())
		throw NException::RuntimeException(toString("Program " + command.absoluteFilePath() + " not executable/available"));

	QStringList arguments;
	arguments.push_back("-T");
	if (_title.isNull())
		arguments.push_back(argumentString);
	else
		arguments.push_back(_title);
	arguments.push_back("-e");
	// execute using the shell
	arguments.push_back("/bin/sh");
	arguments.push_back("-c");
	QString fullArgumentString;
	fullArgumentString += "(";
		if (root)
		{
			fullArgumentString += "echo \"Please enter root password\" ";
			switch (gainRootCommand())
			{
				case SU:
					fullArgumentString += "; " + GainRootPaths::su + " -c ";
					// for su the command to be executed must be ONE argument and since it
					// contains spaces it must be quoted
					fullArgumentString += "\"" + argumentString + "\"";
					break;
				//
				case SUDO:
					fullArgumentString += "; " + GainRootPaths::sudo + " ";
					// for sudo, everything following the sudo command is passed to 
					// the target application, so there must be no quoting
					fullArgumentString += argumentString;
					break;
			}
		}
		else
		{
			fullArgumentString += argumentString;
		}
		
		fullArgumentString += "&& echo \"\nExecution completed successfully!\"";
	fullArgumentString += ")";
	fullArgumentString += "|| ( echo \"\nExecution failed. \" ; read dummy ) ";
	
	arguments.push_back(fullArgumentString);
	// forward the signal
	connect(_pProcess, SIGNAL(finished(int)), this, SLOT(onProcessExited()));
	_pProcess->start(terminalEmulator.absoluteFilePath(), arguments);
	return true;
}

bool RunCommandInXterm::start()
{
	return start(false);
}


bool RunCommandInXterm::startAsRoot()
{
	if (geteuid() != 0)
		return start(true);
	else 
		return start(false);
}

void RunCommandInXterm::onProcessExited()
{
	_pProcess->deleteLater();	// delete during the next event loop
	_pProcess = 0;
	emit processExited();
	emit quit();
}

void RunCommandInXterm::setTitle(const QString& title)
{
	_title = title;
}

bool RunCommandInXterm::waitForFinished(int msecs)
{
	// if the process has finished
	if (_pProcess == 0)
		return true;
	// if the process is still running
	return _pProcess->waitForFinished(msecs);
}

bool RunCommandInXterm::finished()
{
	// process is finished, if it is set back to 0
	return _pProcess == 0;
}


};
