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

#include <unistd.h>	// for usleep
#include <sys/wait.h>	// for wait
#include <stdio.h>


#include <QProcess>
#include <QApplication>
#include <QTime>
#include <QtDebug>

#include "runcommandforoutput.h"


using namespace std;



namespace NApplication {

RunCommandForOutput::RunCommandForOutput(const QString& command)
	: _command(command)
{
	_finished = false;
	_pProcess = new QProcess(this);
	connect(_pProcess, SIGNAL(
readyReadStandardOutput()), SLOT(onReadyReadStdout()));
	connect(_pProcess, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(onProcessExited()));
}


RunCommandForOutput::~RunCommandForOutput()
{
// 	qDebug("Destructing RunCommandForOutput");
	delete _pProcess;
}


void RunCommandForOutput::start()
{
	_pProcess->start(_command, _arguments);
}

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

void RunCommandForOutput::onReadyReadStdout()
{
	while ( _pProcess->canReadLine() )
	{
		_output.push_back(_pProcess->readLine());
	}
}

void RunCommandForOutput::onProcessExited()
{
	while ( _pProcess->canReadLine() )
	{
		_output.push_back(_pProcess->readLine());
	}
	emit (processExited(this));
}

bool RunCommandForOutput::normalExit()
{ 
	return _pProcess->exitStatus() == QProcess::NormalExit; 
}


// Thanks to <http://www.mrunix.de/forums/showthread.php?t=33079&goto=nextoldest>
// for the hint to use popen, it seems QT lacks some functionality here
bool RunCommandForOutput::run(const QString& command, size_t maximumLineLength)
{
	QString out;
#ifdef __DEBUG
    QTime startTime = QTime::currentTime();
#endif
    FILE* pipe = popen(command.toLatin1(), "r");
	if (maximumLineLength==0)
	{
		char c;
		while( (c = getc(pipe)) != EOF )
		{
			if (c=='\n')
			{
				_output.push_back(out);
				out.truncate(0);
			}
			else
				out += c;
		}
	}
	else
	{
		char* chars = new char[maximumLineLength];	// current maximum line
		while (fgets(chars, maximumLineLength, pipe) != 0)
		{
			_output.push_back(chars);
			_output.last().truncate(_output.last().length()-1);	// remove the trailing newline
		}
		delete[] chars;
	}
	int exitStatus = pclose(pipe);
#ifdef __DEBUG
    // wrong results when passing 0:00 but who is going to develop at that time? ;)
    qDebug() << "Time elapsed for " << command << ": " << QTime::currentTime().msecsSinceStartOfDay() - startTime.msecsSinceStartOfDay() << " ms";
#endif
	return exitStatus == 0;
}

};
