//
// C/C++ headers
//
#include <fstream>
#include <sstream>
#include <iostream>
//
// ROOT headers
//
#include <TSystem.h>
#include <TString.h>
#include <TSQLServer.h>
//
// This package headers
//
#include <RunInfo.h>
#include <RunInfoVerl2.h>
//
using namespace std;
//
// Usage subroutine
//
void usage(){
  printf("\nUsage:\n");
  printf("\n RunInfo [-v] [-h] [--version] -idRun ID_RUN [-processFile filename] [-processFolder folder]\n");
  printf("\n --version       print informations about compilation and exit\n");
  printf("\n -h | --help     print this help and exit \n");
  printf("\n -v | --verbose  be verbose [default: print nothing on STDOUT]\n");
  printf("\n -idRun          ID_RUN: ID number of the run to be processed \n");
  printf("\n -processFile    filename : output filename [default ID_RUN.Level2.root]\n");
  printf("\n -processFolder  where to store temporary data [default \"runinfoFolder\"]\n");
  printf("\n Notice that parameter order does not matter. \n");
  printf("\nExample: \n\nRunInfo -idRun 1085 -processFile nomefile.root\n\n");
};
//
Bool_t existfile(TString filename){
    ifstream myfile;
    myfile.open(filename.Data());
    if ( !myfile ){
      return(false);
    };
    myfile.close();
    return(true);
}
//
Bool_t debug = false;
//
//
// Here the main
//
int main(int numinp, char *inps[]){
  //
  // Variables booking
  //
  int nul = 0;
  Int_t error = 0;
  Bool_t beverbose = false;
  ULong64_t run = 0;
  TString filename;
  TString processFolder = "runinfoFolder";
  TSQLServer *dbc = 0;
  Bool_t givenid = false;
  //
  // Checking input parameters
  //
  if ( numinp > 1 ){
    for ( int i = 0; i < numinp; i++ ){
      if ( !strcmp(inps[i],"--version") ){
	RunInfoInfo(true);
	exit(0);
      };
      if ( !strcmp(inps[i],"-h") || !strcmp(inps[i],"--help") ){
	usage();
	exit(0);
      };
      if ( !strcmp(inps[i],"-idRun") ) {
	if ( numinp-1 < i+1 ){
	  usage();
	  exit(-3);
	};
	givenid = true;
	char *pEnd;	
	run = strtoull(inps[i+1],&pEnd,0);	
      };
      if ( !strcmp(inps[i],"-processFile") ) {
	if ( numinp-1 < i+1 ){
	  usage();
	  exit(-3);
	};
	filename = (TString)inps[i+1];	
      };
      if ( !strcmp(inps[i],"-processFolder") ) {
	if ( numinp-1 < i+1 ){
	  usage();
	  exit(-3);
	};
	processFolder = (TString)inps[i+1];	
      };
      if ( !strcmp(inps[i],"-v") || !strcmp(inps[i],"--verbose") ) beverbose = true;
    };
  } else {
    //
    // no input parameters exit with error, we need at least the run id.
    //
    printf(" RunInfo - ERROR: you must provide a run number (at least -1)\n");
    exit(-1);
  };
  //
  // If not in verbose mode redirect to /dev/null the stdout and stderr
  //
  if ( !beverbose ){
    nul = open("/dev/null", O_CREAT | O_RDWR,S_IREAD | S_IWRITE);
    dup2(nul,1);
    dup2(nul,2);
  };
  //
  // Check that an input run number has been given
  //
  if ( !givenid ) {
    printf(" RunInfo - ERROR: you must provide a run number (at least -1)\n");
    exit(-1);
  };
  //
  char *version = RunInfoInfo(false);
  //
  // Start:
  //
  printf("\n Welcome to the RunInfo software, version %s \n",version);
  //
  // Connect to the DB
  //
  printf("\nConnecting to database... \n"); 
  //
  dbc = TSQLServer::Connect("mysql://localhost/pamelaprod","anonymous","");
//
  if( !dbc ) {
    printf(" RunInfo - ERROR: problems connecting to the DB (check username and passwd), exiting...\n\n");
    exit(-2);    
  };
  bool connect = dbc->IsConnected();
  //
  if( !connect ) {
    printf(" RunInfo - ERROR: problems connecting to the DB (check username and passwd), exiting...\n\n");
    exit(-2);    
  };
  printf("...connected! \n\n");
  //
  //
  //
  stringstream name;
  name.str("");
  if ( run != 0ULL ){
    //
    // Run is not 0, we must process only one run .
    //
    //
    // If no filename is given, use the deafult one run_id.Level2.root.
    //
    if ( !strcmp(filename.Data(),"") ){
      name << run << ".Level2.root";
    } else {
      name << filename.Data();
    };
    //
  } else {
    //
    // Run is 0, we must process all entries in the given file.
    //
    //
    // OUCH! no filename has been given, run out!
    //
    if ( !strcmp(filename.Data(),"") ) {
      printf(" RunInfo - ERROR: processing all runs but no filename is given\n");
      exit(-4);
    };
    name << filename.Data();
    //
  };
  TString outputfile;
  ItoRunInfo *runinfo = 0;
  TFile *file = 0;
  //
  stringstream temprname;
  const char* routdir = gSystem->WorkingDirectory();
  temprname.str("");
  temprname << routdir;
  temprname << "/" << processFolder.Data();  
  //
  // Output file is "outputfile"
  //
  outputfile = name.str().c_str(); 
  printf("\n Output filename is: \n %s \n\n",outputfile.Data());
  //
  // Check if file exists, if not exit with error (calorimeter needs tracker data).
  //
  if ( !existfile(outputfile.Data()) ) {
    printf(" RunInfo: creating LEVEL2 file \n");
  };
  // 
  // OK, file exists, open it in "update" mode. 
  //
  file = new TFile(outputfile.Data(),"UPDATE");
  if ( !file->IsOpen() ){
    printf(" RunInfo - ERROR: cannot open file for writing\n");
    error = -802;
    goto theend;
  };
  //
  runinfo = new ItoRunInfo(dbc,file,processFolder);
  error = runinfo->Update(run,"NONE","");
  gSystem->Unlink(temprname.str().c_str());
  //  if ( error < 0 ) goto theend;
  runinfo->Close();
  if ( file ){
    file->Write();
    file->Close();
  };
  //
 theend:
  //
  // Close the DB connection
  //
  printf("\nClose the connection to the database... \n");
  dbc->Close();
  printf("...connection terminated!\n\n");   
  //
  // Close redirection if the case.
  //
  if ( !beverbose ) close(nul);
  //
  // Return "error"
  //
  exit(error);
}
