//
// C/C++ headers
//
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string.h>
//
// ROOT headers
//
#include <TSQLServer.h>
#include <TString.h>
#include <TTimeStamp.h>
#include <TFile.h>
#include <TSystem.h>
#include <TChain.h>
#include <TH1.h>
#include <TTree.h>
#include <TKey.h>
#include <Riostream.h>
#include <TObjString.h>
#include <TClass.h>
//
// Detector's package headers
//
#include <RunGlue.h>
//
using namespace std;
//
//
//
#include <PadmeAmidalaVerl2.h>
//
//
// Usage subroutine
//
void amidalausage(){
  printf("\nUsage:\n");
  printf("\n Amidala [ options ]\n");
  printf("\n Options are:\n\n");
  printf(" --version        print informations about compilation and exit\n");
  printf(" -h | --help      print this help and exit \n");
  printf(" -g | --debug     set debug flag\n");
  printf(" -p | --pedantic  merge only when all level2 run files are present (default NOT pedantic, merge whatever it finds)\n");
  printf(" -idRun run       merge all runs in the directory which have the same date of run \"run\"\n");
  printf(" -outdir dir      output directory \"dir\"\n");
  printf(" -dir dir         merge all runs in the directory \"dir\"\n");
  printf(" -d | -delete     delete original DarthVader runs once merged\n");
  printf(" -no-DBupdate     do not update the DB\n");
  printf(" -host            name of the DB host [default = $PAM_DBHOST or mysql://localhost/pamelaprod]\n");
  printf(" -user            username for the DB connection [default = $PAM_DBUSER or \"anonymous\"] \n");
  printf(" -psw             password for the DB connection [default = $PAM_DBPSW or \"\"]\n");
  printf("\nExamples: \n");
  printf("      Amidala -idRun 1085 \n");
  printf("      Amidala -dir /home/pamela/level2/ \n\n");
};
//
// Here the main
//
int main(int numinp, char *inps[]){
  //
  // Variables booking
  //
  TString message;
  //
  UInt_t run = 0;
  //
  TString dir = "";
  TString outdir = "";
  TString dectlist = "";
  //
  TSQLServer *dbc = 0;
  TString host = "mysql://localhost/pamelaprod";
  TString user = "anonymous";
  TString psw = "";
  Bool_t debug = false;
  Bool_t delop = false;
  Bool_t dbup = true;
  Bool_t pedantic = false;
  //
  const char *pamdbhost=gSystem->Getenv("PAM_DBHOST");
  const char *pamdbuser=gSystem->Getenv("PAM_DBUSER");
  const char *pamdbpsw=gSystem->Getenv("PAM_DBPSW");
  if ( !pamdbhost ) pamdbhost = "";
  if ( !pamdbuser ) pamdbuser = "";
  if ( !pamdbpsw ) pamdbpsw = "";
  if ( strcmp(pamdbhost,"") ) host = pamdbhost;
  if ( strcmp(pamdbuser,"") ) user = pamdbuser;
  if ( strcmp(pamdbpsw,"") ) psw = pamdbpsw;
  //
  stringstream myquery;
  //
  // Checking input parameters
  //
  Int_t i = 0;
  if ( numinp > 1 ){
    while ( i < numinp ){
      if ( !strcmp(inps[i],"--version") ){
	AmidalaInfo(true);
	exit(0);
      };
      if ( !strcmp(inps[i],"-h") || !strcmp(inps[i],"--help") ){
	amidalausage();
	exit(0);
      };
      if ( !strcmp(inps[i],"-g") || !strcmp(inps[i],"--debug") ){
	debug = true;
      };
      if ( !strcmp(inps[i],"-d") || !strcmp(inps[i],"-delete") ){
	delop = true;
      };
      if ( !strcmp(inps[i],"-p") || !strcmp(inps[i],"--pedantic") ){
	pedantic = true;
      }
      if ( !strcmp(inps[i],"-no-DBupdate") ){
	dbup = false;
      };
      if ( !strcmp(inps[i],"-idRun") ) {
	if ( numinp-1 < i+1 ) {
	  amidalausage();
	  exit(-3);
	};
	run = (UInt_t)atoll(inps[i+1]);	
      };
      if ( !strcmp(inps[i],"-dir") ) {
	if ( numinp-1 < i+1 ){
	  amidalausage();
	  exit(-3);
	};
	dir = (TString)inps[i+1];	
      };
      if ( !strcmp(inps[i],"-outdir") ) {
	if ( numinp-1 < i+1 ){
	  amidalausage();
	  exit(-3);
	};
	outdir = (TString)inps[i+1];	
      };
      if ( !strcmp(inps[i],"-host") ) {
	if ( numinp-1 < i+1 ){
	  amidalausage();
	  exit(-3);
	};
	host = (TString)inps[i+1];	
      };
      if ( !strcmp(inps[i],"-user") ) {
	if ( numinp-1 < i+1 ){
	  amidalausage();
	  exit(-3);
	};
	user = (TString)inps[i+1];	
      };
      if ( !strcmp(inps[i],"-psw") ) {
	if ( numinp-1 < i+1 ){
	  amidalausage();
	  exit(-3);
	};
	psw = (TString)inps[i+1];	
      };
      //
      if ( !strcmp(inps[i],"-CAL") ) {
	dectlist +=" -CAL";
      };
      if ( !strcmp(inps[i],"-CAL1") ) {
	dectlist +=" -CAL1";
      };
      if ( !strcmp(inps[i],"-TRK") ) {
	dectlist +=" -TRK";
      };
      if ( !strcmp(inps[i],"-TRK1") ) {
	dectlist +=" -TRK1";
      };
      if ( !strcmp(inps[i],"-TRKh") ) {
	dectlist +=" -TRKh";
      };
      if ( !strcmp(inps[i],"-TOF") ) {
	dectlist +=" -TOF";
      };
      if ( !strcmp(inps[i],"-TRG") ) {
	dectlist +=" -TRG";
      };
      if ( !strcmp(inps[i],"-S4") ) {
	dectlist +=" -S4";
      };
      if ( !strcmp(inps[i],"-ND") ) {
	dectlist +=" -ND";
      };
      if ( !strcmp(inps[i],"-AC") ) {
	dectlist +=" -AC";
      };
      if ( !strcmp(inps[i],"-RUN") ) {
	dectlist +=" -RUN";
      };
      if ( !strcmp(inps[i],"-ORB") ) {
	dectlist +=" -ORB";
      };
      //
      if ( !strcmp(inps[i],"-all") || !strcmp(inps[i],"-ALL") ) {
	dectlist +=" -ALL";	  
      };
      //
      if ( !strcmp(inps[i],"+all") || !strcmp(inps[i],"+ALL") ) {
	dectlist +=" +ALL";	  
      };
      if ( !strcmp(inps[i],"+auto") || !strcmp(inps[i],"+AUTO") ) {
	dectlist +=" +AUTO";	  
      };
      if ( !strcmp(inps[i],"+CAL") ) {
	dectlist +=" +CAL";
      };
      if ( !strcmp(inps[i],"+CAL1") ) {
	dectlist +=" +CAL1";
      };
      if ( !strcmp(inps[i],"+TRK") ) {
	dectlist +=" +TRK";
      };
      if ( !strcmp(inps[i],"+TRK1") ) {
	dectlist +=" +TRK1";
      };
      if ( !strcmp(inps[i],"+TRKh") ) {
	dectlist +=" +TRKh";
      };
      if ( !strcmp(inps[i],"+TOF") ) {
	dectlist +=" +TOF";
      };
      if ( !strcmp(inps[i],"+TRG") ) {
	dectlist +=" +TRG";
      };
      if ( !strcmp(inps[i],"+S4") ) {
	dectlist +=" +S4";
      };
      if ( !strcmp(inps[i],"+ND") ) {
	dectlist +=" +ND";
      };
      if ( !strcmp(inps[i],"+AC") ) {
	dectlist +=" +AC";
      };
      if ( !strcmp(inps[i],"+RUN") ) {
	dectlist +=" +RUN";
      };
      if ( !strcmp(inps[i],"+ORB") ) {
	dectlist +=" +ORB";
      };
      //
      i++;
    };
    //
  } else {
    //
    // no input parameters exit with error, we need at least the run id.
    //
    amidalausage();
    exit(-2);
  };
  //
  if ( run && strcmp(dir.Data(),"") ){
    amidalausage();
    printf(" Cannot give as input both ID run and directory \n\n");
    exit(-2);
  };
  if ( !run && !strcmp(dir.Data(),"") ){
    amidalausage();
    printf(" You must give as input or an ID run or a directory \n\n");
    exit(-2);
  };
  //
  // Connect to the DB
  //
  dbc = TSQLServer::Connect(host.Data(),user.Data(),psw.Data());
  if( !dbc ) throw -2;    
  //
  bool connect = dbc->IsConnected();
  //
  if( !connect ){
    printf(" Error, not connected to DB\n");
    exit(-1);
  };    
  //
  myquery.str("");
  myquery << "SET time_zone='+0:00';";
  delete dbc->Query(myquery.str().c_str());
  delete dbc->Query("SET sql_mode = 'NO_UNSIGNED_SUBTRACTION';");
  //
  RunGlue *rg = new RunGlue(dbc,run,dir,outdir);
  //
  if ( debug ) rg->SetDebug(true);
  if ( !dbup ) rg->SetUpgrade(false);
  rg->SetDList(dectlist);
  //
  TList *l = 0;
  //
  Int_t RET=0;
  //
  //  TString treelist="+AUTO";
  //
  while ( !rg->End() ){
    //
    l = rg->GetRunList();
    //
    if ( l && !(rg->HasDiscardedRuns() && pedantic) ){
      //
      if ( rg->FileIsOpen() ){
	//
	rg->MergeRootfile(l);
	//
	if ( dbup ) rg->UpdateDB(l);
	//
	if ( delop ) rg->DeleteRunFiles(l);
	//
	rg->Clean();
	//
      } else {
	RET = 255;
      };
    } else {
      RET = 255;
      if (rg->HasDiscardedRuns() && pedantic){
        printf(" Missing runs (and pedantic selected), cannot merge file %s \n",rg->GetFilename().Data());
        rg->Clean();
      }
    }
    delete l;
    //
  }
  //
  delete rg;
  //
  // Close the DB connection
  //
  if ( dbc ) dbc->Close();
  //
  if ( debug ) printf(" exit with error code %i \n",RET);
  // 
  printf("\n");
  //
  exit(RET);
}
