/*

  Managing of external processes


  Copyright © 2011-5, 2018-9 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack 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.

  Munipack 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 Munipack.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef _MUNIPACK_CONFIG_H_
#define _MUNIPACK_CONFIG_H_

#include <wx/wx.h>
#include <wx/app.h>
#include <wx/process.h>
#include <wx/event.h>
#include <wx/stopwatch.h>
#include <queue>

class MuniProcess: public wxProcess
{
public:
  MuniProcess(wxEvtHandler *, const wxString&,
	      const wxArrayString& =wxArrayString());
  virtual ~MuniProcess();

  virtual void OnPreProcess() {}
  virtual void OnStart();
  virtual void OnPostProcess() {}
  wxKillError Kill(wxSignal sig =wxSIGTERM, int flags =wxKILL_NOCHILDREN);

  void Write(const char *);
  void Write(const wxString&, ...);
  int GetExitCode() const { return exitcode; }
  wxArrayString GetInput() const { return Input; }
  wxArrayString GetOutput() const { return Output; }
  wxArrayString GetErrors() const { return Error; }
  void AddInput(const wxArrayString&);
  wxString GetCommand() const { return command; }
  void SetEcho(bool);

protected:

  wxString command;
  wxArrayString Input,Output,Error;
  int exitcode;

private:

  wchar_t **argv;
  wxTimer timer;
  int tick;
  wxStopWatch stopwatch;
  size_t Index;
  bool echo;

  void Send();
  bool Receive();
  void OnTimer(wxTimerEvent&);
  void OnTerminate(int,int);
  bool StopLine(const wxString&, int&) const;
  void SaveErrorLog() const;

  void SetRuntimeEnvironment();
  void SetFitsKeys();
};

class MuniPipe: public wxEvtHandler
{
public:
  MuniPipe(wxEvtHandler * =0);
  virtual ~MuniPipe();

  void SetHandler(wxEvtHandler *);
  void push(MuniProcess *);
  void Start();
  void Stop();
  void SetExitCode(int e) { exitcode = e; }
  int GetExitCode() const { return exitcode; }
  bool empty() const { return procs.empty(); };
  wxArrayString GetOutput() const;
  wxArrayString GetErrors() const;

private:

  wxEvtHandler *parent;
  std::queue<MuniProcess *> procs;
  wxArrayString OutputBuffer,ErrorBuffer;
  int exitcode;

  void OnFinish(wxProcessEvent&);

};

#endif
