/***************************************************************************
**
**  This file is part of dinverext.
**
**  dinverext 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.
**
**  dinverext 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 Foobar.  If not, see <http://www.gnu.org/licenses/>
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2007-04-11
**  Copyright: 2007-2019
**    Marc Wathelet
**    Marc Wathelet (LGIT, Grenoble, France)
**
***************************************************************************/

#include <QProcess>

#include <QGpCoreTools.h>
#include "ExtTarget.h"

/*!
  \class ExtTarget ExtTarget.h
  \brief Brief description of class still missing

  Full description of class still missing
*/

const QString ExtTarget::xmlExtTargetTag="ExtTarget";

ExtTarget::ExtTarget(const ExtTarget& o)
    : XMLClass()
{
  _command=o._command;
  _workingDirectory=o._workingDirectory;
}

void ExtTarget::xml_writeProperties(XML_WRITEPROPERTIES_ARGS) const
{
  TRACE;
  Q_UNUSED(context)
  writeProperty(s, "command", _command);
  writeProperty(s, "workingDirectory", _workingDirectory);
}

XMLMember ExtTarget::xml_member(XML_MEMBER_ARGS)
{
  TRACE;
  Q_UNUSED(attributes)
  Q_UNUSED(context)
  if(tag=="command" ) return XMLMember(0);
  else if(tag=="workingDirectory" ) return XMLMember(1);
  else return XMLMember(XMLMember::Unknown);
}

bool ExtTarget::xml_setProperty(XML_SETPROPERTY_ARGS)
{
  TRACE;
  Q_UNUSED(tag)
  Q_UNUSED(attributes)
  Q_UNUSED(context)
  switch (memberID) {
  case 0: _command=content.toString(); return true;
  case 1: _workingDirectory=content.toString(); return true;
  default: return false;
  }
}

bool ExtTarget::isOk(int nParams)
{
  TRACE;
  if(_command.isEmpty()) {
    App::log(tr("Empty command, computing of misfit disabled. A uniform null misfit will be returned for each model.\n") );
    return true;
  }
  QDir d(_workingDirectory);
  // Write fake 'parameter' file
  QFile fp(d.absoluteFilePath("parameters"));
  if(!fp.open(QIODevice::WriteOnly)) {
    App::log(tr("Cannot write to file %1").arg(d.absoluteFilePath("parameters\n")) );
    return false;
  }
  QTextStream s(&fp);
  for(int i=0;i<nParams;i++) {
    s << 0.0 << "\n";
  }
  fp.close();
  QProcess p;
  p.setWorkingDirectory(_workingDirectory);
  p.start(_command);
  while(!p.waitForStarted (1000) && p.state()==QProcess::Starting) {}
  while(!p.waitForFinished (1000) && p.state()==QProcess::Running) {}
  switch(p.error()) {
  case QProcess::FailedToStart:
    App::log(tr("%1 failed to start. Either %1 is missing, or you may have insufficient permissions to invoke it.\n")
              .arg(_command));
    return false;
  case QProcess::Crashed:
    App::log(tr("%1 crashed some time after starting successfully.\n").arg(_command));
    return false;
  default:
    break;
  }
  return true;
}
