/**
 * \file GLTables.cpp
 * \author Elena Vannuccini
 * 
 * The file contains implementation of the methods to query the DB.
 */
//
#include <GLTables.h>
#include <sstream>
//
//
//
using namespace std;
//extern Bool_t debug;

GL_RUN::GL_RUN() {
  ID                         = 0ULL;
  ID_REG_RUN                 = 0ULL;
  ID_REG_RUN_L2              = 0ULL;
  RUNHEADER_TIME             = 0ULL;
  RUNTRAILER_TIME            = 0ULL;
  EV_REG_PHYS_FROM           = 0; 
  EV_REG_PHYS_TO             = 0;  
  EV_REG_RUNHEADER           = 0;  
  EV_REG_RUNTRAILER          = 0;  
  TRK_CALIB_USED             = 0;
  EFF_WRK_SCHEDULE = 0;
  PRH_VAR_TRG_MODE_A     = 0;
  PRH_VAR_TRG_MODE_B     = 0;
  ACQ_BUILD_INFO             = 0;
  ACQ_VAR_INFO               = 0;
}

GL_ROOT::GL_ROOT(){
  ID     = 0ULL;
  ID_RAW = 0ULL;
  PATH   = "";
  NAME   = "";
}

GL_PARAM::GL_PARAM(){
  ID     = 0ULL;
  PATH   = "";
  NAME   = "";
  DESCR  = "";
  FROM_TIME = 0ULL;
  TO_TIME   = 0ULL;
}

GL_TRK_CALIB::GL_TRK_CALIB(){
  ID               = 0ULL;
  ID_REG_CALIBTRK  = 0ULL;
  EV_REG_CALIBTRK1 = 0;
  EV_REG_CALIBTRK2 = 0;
  FROM_TIME = 0ULL;
  TO_TIME   = 0ULL;
}

GL_CALO_CALIB::GL_CALO_CALIB(){
  ID        = 0ULL;
  ID_REG_CALIBCALPED  = 0ULL;
  EV_REG_CALIBCALPED = 0;
  FROM_TIME = 0ULL;
  TO_TIME   = 0ULL;
  SECTION   = 0;
}

GL_S4_CALIB::GL_S4_CALIB(){
  ID        = 0ULL;
  ID_REG_CALIBS4  = 0ULL;
  EV_REG_CALIBS4 = 0;
  FROM_TIME = 0ULL;
  TO_TIME   = 0ULL;
  PARAM_FIT0 = 0;
  PARAM_FIT1 = 0;
}// ****************************************************
/**
 * Function to query the GL_RUN  table of the DB.
 *
 * \param  RUN id
 * \return struct of type GL_RUN _data, which stores the query result
 *
 */
Int_t GL_RUN::Query_GL_RUN(ULong64_t run, TSQLServer *dbc){
  //    Bool_t debug = 1;
  // MySQL variables
  TSQLResult *pResult;
  TSQLRow *Row;
  int t;
  int r;
  char *pEnd;
  stringstream myquery;
  // ----------------
  // NB! unsigned long long integers: when set to a number use ULL to store the correct number
  myquery.str("");
  myquery << " select ";
  //    myquery << " * ";
  myquery << " ID";
  myquery << ",ID_REG_RUN";
  myquery << ",ID_REG_RUN_L2";
  myquery << ",RUNHEADER_TIME";
  myquery << ",RUNTRAILER_TIME";
  myquery << ",EV_REG_PHYS_FROM";
  myquery << ",EV_REG_PHYS_TO";
  myquery << ",EV_REG_RUNHEADER";
  myquery << ",EV_REG_RUNTRAILER";
  myquery << ",TRK_CALIB_USED";
  myquery << ",EFF_WRK_SCHEDULE";
  myquery << ",PRH_VAR_TRG_MODE_A";
  myquery << ",PRH_VAR_TRG_MODE_B";
  myquery << ",ACQ_BUILD_INFO";
  myquery << ",ACQ_VAR_INFO";
  myquery << " from GL_RUN where ID=" << run << ";";
  pResult = dbc->Query(myquery.str().c_str());
  if(!pResult->GetRowCount())return(-50);//throw -50;
  for( r=0; r < 1000; r++){ 
      Row = pResult->Next();      
      if( Row == NULL ) break;
      for( t = 0; t < pResult->GetFieldCount(); t++){ 
	  if (t== 0) ID               = strtoull(Row->GetField(t),&pEnd,0);
	  if (t== 1) ID_REG_RUN       = strtoull(Row->GetField(t),&pEnd,0);
	  if (t== 2) ID_REG_RUN_L2    = strtoull(Row->GetField(t),&pEnd,0);
	  if (t== 3) RUNHEADER_TIME   = strtoull(Row->GetField(t),&pEnd,0); 
	  if (t== 4) RUNTRAILER_TIME  = strtoull(Row->GetField(t),&pEnd,0); 
	  if (t== 5) EV_REG_PHYS_FROM = atoi(Row->GetField(t));
	  if (t== 6) EV_REG_PHYS_TO   = atoi(Row->GetField(t));
	  if (t== 7) EV_REG_RUNHEADER = atoi(Row->GetField(t));
	  if (t== 8) EV_REG_RUNTRAILER= atoi(Row->GetField(t));
	  if (t== 9) TRK_CALIB_USED   = atoi(Row->GetField(t));
	  if (t==10) EFF_WRK_SCHEDULE  = atoi(Row->GetField(t));
	  if (t==11) PRH_VAR_TRG_MODE_A      = atoi(Row->GetField(t));
	  if (t==12) PRH_VAR_TRG_MODE_B      = atoi(Row->GetField(t));
	  if (t==13) ACQ_BUILD_INFO   = atoi(Row->GetField(t));
	  if (t==14) ACQ_VAR_INFO     = atoi(Row->GetField(t));
      };
  };
  delete pResult;

  return 0;

};
// ****************************************************
/**
 * Function to query the GL_ROOT table of the DB.
 *
 * \param  entry ID
 * \return struct of type GL_ROOT_data, which stores the query result
 */
Int_t GL_ROOT::Query_GL_ROOT(ULong64_t id, TSQLServer *dbc){

  // MySQL variables
  TSQLResult *pResult;
  TSQLRow *Row;
  int t;
  int r;
  stringstream myquery;
  // ----------------

  myquery.str("");
  myquery << "select ";
  myquery << " ID"; 
  myquery << ",ID_RAW"; 
  myquery << ",PATH"; 
  myquery << ",NAME"; 
  myquery << " from GL_ROOT where ID=" << id << ";";    
  //  if ( debug ) printf("Query:\n              \"%s\" \n",myquery.str().c_str());  
  pResult = dbc->Query(myquery.str().c_str());
  if(!pResult->GetRowCount())return (-51); //throw -51;
  for( r=0; r < 1000; r++){ 
      Row = pResult->Next();      
      if( Row == NULL ) break;
      for( t = 0; t < pResult->GetFieldCount(); t++){ 
	  if(t==0) ID     = atoi(Row->GetField(t));
	  if(t==1) ID_RAW = atoi(Row->GetField(t));
	  if(t==2) PATH   = Row->GetField(t);
	  if(t==3) NAME   = Row->GetField(t);
      };
  };
  delete pResult;   
  return 0;
};
// ****************************************************
/**
 * Function to query the GL_TRK_CALIB table of the DB.
 *
 * \param  run starting time
 * \return struct of type GL_TRK_CALIB_data, which stores the query result
 */
Int_t GL_TRK_CALIB::Query_GL_TRK_CALIB(ULong64_t time, TSQLServer *dbc){
  // MySQL variables
  TSQLResult *pResult;
  TSQLRow *Row;
  int t;
  int r;
  char *pEnd;
  stringstream myquery;
  // ----------------
  myquery.str("");
  myquery << "select * from GL_TRK_CALIB where FROM_TIME <= "<< time;
  myquery << " ORDER BY FROM_TIME DESC LIMIT 1;";      
  pResult = dbc->Query(myquery.str().c_str()); 
  if(!pResult->GetRowCount())return (-53);//throw -53;
  for( r=0; r < 1000; r++){ 
      Row = pResult->Next();     
      if( Row == NULL ) break;
      for( t = 0; t < pResult->GetFieldCount(); t++){ 
	  if (t==0) ID               = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==1) ID_REG_CALIBTRK  = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==2) EV_REG_CALIBTRK1 = atoi(Row->GetField(t));
	  if (t==3) EV_REG_CALIBTRK2 = atoi(Row->GetField(t));
	  if (t==4) FROM_TIME = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==5) TO_TIME   = strtoull(Row->GetField(t),&pEnd,0);	      
	  //      if ( debug ) printf(" Row %i value = %s \n",t,Row->GetField(t));
      };
  };
  delete pResult;     
  //
  if(TO_TIME < time)return(51);
  //
  return 0;
};

// ****************************************************
/**
 * Function to query the GL_CALO_CALIB table of the DB.
 *
 * \param  run starting time
 * \return struct of type GL_CALO_CALIB_data, which stores the query result
 */
Int_t GL_CALO_CALIB::Query_GL_CALO_CALIB(ULong64_t time, Int_t section, TSQLServer *dbc){
  //    Bool_t debug = 1;
  // MySQL variables
  TSQLResult *pResult;
  TSQLRow *Row;
  int t;
  int r;
  char *pEnd;
  stringstream myquery;
  // ----------------
  myquery.str("");
  myquery << "select ID_REG_CALIBCALPED, FROM_TIME, TO_TIME, EV_REG_CALIBCALPED from GL_CALO_CALIB where SECTION=" << section;
  myquery << " and FROM_TIME <= " << time;
  myquery << " and TO_TIME >= " << time;
  myquery << " ORDER BY FROM_TIME DESC LIMIT 1;";
  //
  //  if ( debug ) printf("\n Querying DB for data files informations...\n");
  //  if ( debug ) printf("The query is:\n              \"%s\" \n",myquery.str().c_str());
  //
  pResult = dbc->Query(myquery.str().c_str());
  if(!pResult->GetRowCount())return (-54);//throw -54;
  for ( r = 0 ; r < 10 ; r++ ) {
      Row = pResult->Next();
      if( Row == NULL ) break;
      for( t = 0; t < pResult->GetFieldCount(); t++){
	  //      if ( debug ) printf(" Row %i value = %s \n",t,Row->GetField(t));
	  //	if (t==0) ID                  = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==0) ID_REG_CALIBCALPED  = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==1) FROM_TIME = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==2) TO_TIME   = strtoull(Row->GetField(t),&pEnd,0);	      
	  if (t==3) EV_REG_CALIBCALPED  = atoi(Row->GetField(t));
	  //	if (t==5) SECTION   = atoi(Row->GetField(t));	      	
      };
  };
  pResult->Delete();
  return 0;
};
// ****************************************************
/**
 * Function to query the GL_S4_CALIB table of the DB.
 *
 * \param  run starting time
 * \return struct of type GL_S4_CALIB_data, which stores the query result
 */
Int_t GL_S4_CALIB::Query_GL_S4_CALIB(ULong64_t time, TSQLServer *dbc){
  // MySQL variables
  TSQLResult *pResult;
  TSQLRow *Row;
  int t;
  int r;
  char *pEnd;
  stringstream myquery;
  // ----------------
  myquery.str("");
  myquery << "select * from GL_S4_CALIB where FROM_TIME <= "<< time;
  myquery << " ORDER BY FROM_TIME DESC LIMIT 1;";      
  //  if ( debug ) printf("Query:\n              \"%s\" \n",myquery.str().c_str());
  pResult = dbc->Query(myquery.str().c_str()); 
  if(!pResult->GetRowCount())return (-55);//throw -55;
  for( r=0; r < 1000; r++){ 
      Row = pResult->Next();     
      if( Row == NULL ) break;
      for( t = 0; t < pResult->GetFieldCount(); t++){ 
	  if (t==0) ID               = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==1) ID_REG_CALIBS4  = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==2) EV_REG_CALIBS4 = atoi(Row->GetField(t));
	  if (t==3) FROM_TIME = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==4) TO_TIME   = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==5) PARAM_FIT0   = atof(Row->GetField(t));
	  if (t==6) PARAM_FIT1   = atof(Row->GetField(t));
	  //      if ( debug ) printf(" Row %i value = %s \n",t,Row->GetField(t));
      };
  };
  delete pResult;     
  //
  if(TO_TIME < time)return(51);
  //
  return 0;
};
// ****************************************************
/**
 * Function to query the GL_PARAM table of the DB.
 *
 * \param  run starting time
 * \param  parameter description (DESCR)
 * \return struct of type GL_ROOT_data, which stores the query result
 */
Int_t GL_PARAM::Query_GL_PARAM(ULong64_t time, TString descr, TSQLServer *dbc){
  //    Bool_t debug = 1;
  // MySQL variables
  TSQLResult *pResult;
  TSQLRow *Row;
  int t;
  int r;
  char *pEnd;
  stringstream myquery;
  // ----------------    
  myquery.str("");
  myquery << " select ";
  myquery << " ID, PATH, NAME, DESCR, FROM_TIME,TO_TIME ";
  myquery << " from GL_PARAM ";
  myquery << " where DESCR = '"<<descr<<"' ";
  myquery << " and FROM_TIME <= " << time; 
//  myquery << " ORDER BY FROM_TIME DESC LIMIT 1;";  
  myquery << " ORDER BY TO_TIME DESC LIMIT 1;";  
  //  if ( debug ) printf("Query:\n              \"%s\" \n",myquery.str().c_str());
  pResult = dbc->Query(myquery.str().c_str()); 
  if(!pResult->GetRowCount())return (-52);//throw -52;
  for( r=0; r < 1000; r++){ 
      Row = pResult->Next();     
      if( Row == NULL ) break;
      for( t = 0; t < pResult->GetFieldCount(); t++){ 
	  if (t==0) ID        = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==1) PATH      = Row->GetField(t);// put in fpath the path to that file
	  if (t==2) NAME      = Row->GetField(t);
	  if (t==3) DESCR     = Row->GetField(t);
	  if (t==4) FROM_TIME = strtoull(Row->GetField(t),&pEnd,0);
	  if (t==5) TO_TIME   = strtoull(Row->GetField(t),&pEnd,0);	      
	  //      if ( debug ) printf(" Row %i value = %s \n",t,Row->GetField(t));
      };
  };
  delete pResult; 
  //
  //    if (TO_TIME==0) TO_TIME=(ULong64_t)(1e15); // temporaneo!!!!
  if(TO_TIME==0) TO_TIME = numeric_limits<ULong64_t>::max();
  //
  if(TO_TIME < time) return(51);
  //        
  return 0;   
};
//
ClassImp(GL_TRK_CALIB);
ClassImp(GL_RUN);
ClassImp(GL_ROOT);
ClassImp(GL_PARAM);
ClassImp(GL_S4_CALIB);
ClassImp(GL_CALO_CALIB);
