/**
 * \file gui/mcqr_run_view/mcqrqprocess.cpp
 * \date 12/07/2021
 * \author Thomas Renne
 * \brief Overload the Qprocess for the MCQR process
 */

/*******************************************************************************
 * Copyright (c) 2021 Thomas Renne <thomas.renne@e.email>.
 *
 * This file is part of XTPcpp.
 *
 *     XTPcpp 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 3 of the License, or
 *     (at your option) any later version.
 *
 *     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Thomas Renne <thomas.renne@e.email> - initial API and
 *implementation
 ******************************************************************************/

#include "mcqrqprocess.h"
#include <QDebug>
#include <QSettings>
#include <pappsomspp/pappsoexception.h>

McqrQProcess::McqrQProcess(QObject *parent) : QProcess(parent)
{
  // startRProcess();
}

McqrQProcess::~McqrQProcess()
{
  stopRprocess();
}


void
McqrQProcess::startRprocess()
{
  QString version_return;
  QStringList arguments;

  arguments << "--vanilla"
            << "-q"
            << "--slave";
  QSettings settings;
  QString r_binary_path = settings.value("path/r_binary", "R").toString();
  start(r_binary_path, arguments, QProcess::Append | QProcess::ReadWrite);

  if(!waitForStarted())
    {
      QString err = tr("Could not start R process '%1' with arguments '%2': %3")
                      .arg(r_binary_path)
                      .arg(arguments.join(QStringLiteral(" ")))
                      .arg(errorString());
      throw pappso::PappsoException(err);
    }
}

void
McqrQProcess::stopRprocess()
{

  if(state() == QProcess::Running)
    {
      executeOffTheRecord(QString("quit( save = \"no\")"));
      waitForFinished();
      QProcess::ExitStatus Status = exitStatus();
      qDebug() << Status;
      if(Status != 0)
        {
          // != QProcess::NormalExit
          kill();
          // delete mp_rProcess;
          throw pappso::PappsoException(
            QObject::tr("error executing R Status != 0 "));
        }
    }
}


qint64
McqrQProcess::executeOnTheRecord(const QString &mcqr_code)
{
  m_RscriptRun << mcqr_code;
  return QProcess::write(mcqr_code.toUtf8());
}

const QTextStream &
McqrQProcess::getRScriptRun() const
{
  return m_RscriptRun;
}

qint64
McqrQProcess::executeOffTheRecord(const QString &mcqr_otr)
{
  return QProcess::write(mcqr_otr.toUtf8());
}


void
McqrQProcess::executeMcqrStep(const QString &mcqr_step_name,
                              const QString &mcqr_step)
{

  executeOnTheRecord(
    QString("message(\"MCQRBegin: %1\")\n").arg(mcqr_step_name));

  executeOffTheRecord("vl <- tryCatch({\n");
  executeOnTheRecord(mcqr_step);

  executeOnTheRecord(QString("message(\"MCQREnd: %1\")\n").arg(mcqr_step_name));
  // write(mcqr_step.toUtf8());
  executeOffTheRecord(
    QString(
      "\n},error "
      "= function(err) {\n message(paste(\"Error in %1 : \",err))\n},finally = "
      "function(f) "
      "{\n print(paste(\"e: \", e))\n})\n message(paste(\"Output: \", vl))\n")
      .arg(mcqr_step_name));
}
