/*

  Virtual Observatory capable cone search

  Copyright © 2010 - 2014 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/>.

*/

#include "votable.h"
#include "vocatconf.h"
#include <wx/wx.h>
#include <wx/app.h>
#include <wx/url.h>
#include <wx/filesys.h>
#include <wx/wfstream.h>
#include <wx/txtstrm.h>
#include <wx/fs_inet.h>
#include <list>
#include <cstdio>


using namespace std;

class Cone: public wxAppConsole
{
public:
  bool OnInit();
  int OnRun();
private:
  int conesearch();
};
IMPLEMENT_APP_CONSOLE(Cone)


bool Cone::OnInit()
{
  wxLog::DisableTimestamp();
  return true;
}

int Cone::OnRun()
{
  int exitcode = conesearch();

  // Just strangle workaround.
  // The code simulates STOP commands used on terminate of Fortran programs.
  // We have no faith to exit codes returned by child processes because
  // a correct terminate would leads to generate 'Child process (PID XXX)
  // still alive but pipe closed so generating a close notification'
  // under some GNU/Linux distributions (Fedora). Processing of STOP
  // eliminates use of process execution terminate codes.
  // One looks as a bug of WX.
  fprintf(stderr,"STOP %d\n",exitcode);

  return exitcode;
}

int Cone::conesearch()
{
  const wxString amp("&");
  wxString url, output, backup, type, sort, ra, dec, sr;
  list<wxString> pars;
  bool verbose = false, pipelog = false;

  wxFFileInputStream istream(stdin);
  wxTextInputStream input(istream);

  // replace by using of regex? fortran-fread ?

  while(istream.IsOk() && ! istream.Eof()) {

    wxString line = input.ReadLine();

    if( line.StartsWith("VERBOSE") ) {
      wxLog::SetLogLevel(wxLOG_Debug);
      verbose = GetBool(line);
    }

    if( line.StartsWith("PIPELOG") )
      pipelog = GetBool(line);

    if( line.StartsWith("URL") )
      url = GetString(line);

    if( line.StartsWith("OUTPUT") )
      GetOutput(line,output,backup);

    if( line.StartsWith("TYPE") )
      type = GetString(line);

    if( line.StartsWith("SORT") )
      sort = GetString(line);

    if( line.StartsWith("PAR") )
      pars.push_back(GetString(line));
  }

  wxASSERT(!url.IsEmpty());

  for(list<wxString>::const_iterator a = pars.begin(); a != pars.end(); ++a)
    url += (a != pars.end() ? amp : "") + *a;

  if( verbose ) { wxPrintf("Connecting VO: "+url+"\n"); }

  wxURL u(url);
  VOTable vt(u);

  if( ! vt.IsOk() ) {
    if( pipelog ) wxPrintf("=CONE> Failed to open: `"+url+"'\n");
    if( verbose ) wxPrintf("Failed to open: `"+url+"'\n");
    return 1;
  }

  if( ! sort.IsEmpty() )
    vt.Sort(sort);

  int exitcode = vt.Save(output,backup,type) ? 0 : 1;

  if( exitcode == 0 ) {
    if( pipelog ) wxPrintf("=CONE> %d objects found\n",vt.RecordCount());
    if( verbose ) wxPrintf("Cone search: %d objects found\n",vt.RecordCount());
  }

  return exitcode;
}
