#include "converter.h"

Converter::Converter(QString AppDir, QStringList *myData)
{
    this->AppDir=AppDir;
    this->myData=myData;
}

#ifdef Q_OS_WIN
Converter::Converter(QString AppDir, QStringList *myData, QWinTaskbarProgress *win7TaskBarProgress)
    : Converter(AppDir, myData)
{
    this->win7TaskBarProgress = win7TaskBarProgress;
}
#endif

void Converter::run()
{
    this->myProcess = std::make_unique<QProcess>();
    QString result = QString();
    QString errorMessage = "";
    int numErrors=0;

    this->myProcess->setWorkingDirectory(this->AppDir); // Set working directory (for work with AEI2/Mac OS)

    LOG_INFO << "Setting OniSplit process working dir to " + this->AppDir + ".";

#ifdef Q_OS_WIN
    if(this->win7TaskBarProgress){
        this->win7TaskBarProgress->reset();
        this->win7TaskBarProgress->show();
    }
#endif

    if(this->myData->size()!=1){
#ifdef Q_OS_WIN
        if(this->win7TaskBarProgress){
            this->win7TaskBarProgress->setRange(0,this->myData->size());
        }
#endif
        emit setupPB(this->myData->size());
    }
    else{
#ifdef Q_OS_WIN
        if(this->win7TaskBarProgress){
            this->win7TaskBarProgress->setRange(0,0);
        }
#endif
        emit setupPB(0); //Intermitent bar, we don't have any estimation when the task is done
    }

    for(int i=0; i<this->myData->size(); i++){

        QString commands=this->myData->at(i);
        QString commandToExec;

        int currentIndex=0, nextIndex=0;

        while(true){
            nextIndex=commands.indexOf(GlobalVars::OniSplitProcSeparator,currentIndex+1);

            commandToExec=commands.mid(currentIndex,(nextIndex-currentIndex));
            this->myProcess->start(UtilVago::getOniSplitExecutable() + " " + commandToExec);
            this->myProcess->waitForFinished(-1);

             // If the process has killed there's no need to proceed with reading output or process more commands
            if(this->myProcess == nullptr){

#ifdef Q_OS_WIN
                if(this->win7TaskBarProgress){
                    this->win7TaskBarProgress->hide();
                }
#endif

                this->myProcess.reset(); //delete object and make pointer invalid
                this->myData->clear(); //clean list
                emit conversionAborted();

                return;
            }

            result = this->myProcess->readAllStandardError();

            if(!result.isEmpty()){ //if(!result.startsWith("Importing",Qt::CaseSensitive) && !result.startsWith("Importing",Qt::CaseSensitive)){ //case sensitive is faster
                //catch exception
                LOG_ERROR << "Oni Split Error: \n" + this->myData->at(i) + "\n" + result;
                errorMessage=result;
                numErrors++;
            }

            if(nextIndex==-1){ //we got to the end, stop proccessing commands
                break;
            }
            currentIndex=nextIndex+1; //update currentIndex +1 for start after the separator
        }

#ifdef Q_OS_WIN
        if(this->win7TaskBarProgress){
            this->win7TaskBarProgress->setValue(win7TaskBarProgress->value()+1);
        }
#endif

        emit taskDone();
    }

#ifdef Q_OS_WIN
    if(this->win7TaskBarProgress){
        this->win7TaskBarProgress->hide();
    }
#endif

    this->myProcess.reset(); //delete object and make pointer invalid
    this->myData->clear(); //clean list

    //let's cut it a bit, complete error is in log file.
    if(errorMessage.size()>600){
        //limit it at 400 characters (not counting the warning at the begin)
        errorMessage.remove(299,errorMessage.size()-600);
        errorMessage.insert(299,"\n \t ... \n");
        errorMessage.insert(0,"This error was been shortened. \nSee the complete error at Vago log file.\n\n");
    }

    emit resultConversion(errorMessage,numErrors);
}

// Kill the process if requested
void Converter::terminateCurrProcess(){
    if(this->myProcess != nullptr){
        this->myProcess->kill();
        this->myProcess.reset();
    }

    LOG_INFO << "Received signal to kill current OniSplit operation (user requested).";
}
