
#include <log4cxx/logger.h>
#include <log4cxx/propertyconfigurator.h>
#include "EventReader.h"
#include <time.h>

extern "C" {
    #include <dirent.h>
}



using namespace pamela;
using namespace log4cxx;
using namespace std;
using namespace pamela::techmodel;

static LoggerPtr logger = Logger::getLogger(_T("pamela.techmodel.TechmodelReader"));

int main(int argc, char* argv[]) {
    
    stringstream oss;
    int maxPackets = 0;
    bool multiFile = 0;
    short compression = 3;
    char nomeFileLog[L_tmpnam];
    mkstemp(nomeFileLog);
    DIR *dirp;
    char *outDir = "";
    
    //---------------- Log4cxx configuration-----------------------------------------------
    //BasicConfigurator::configure();
    //Retrieve the rootLogger and append to it a default FileAppender.
    //Note that the priority level of the rootLogger (defined in log4cxx.conf) is unmodified
    //LoggerPtr rootLogger = Logger::getRootLogger();

    //FileAppender *fileAppender = new FileAppender();
    //fileAppender->setFile(pathLog);
    //fileAppender->setAppend(false);
    //fileAppender->setBufferedIO(true); //the default size is 8k
    //fileAppender->setBufferSize(1000000);
    //fileAppender->activateOptions();
    //fileAppender->setLayout(new PatternLayout());

    //FileAppender *fileAppender = new FileAppender(new PatternLayout(), pathLog, false, true, 10000);
    //rootLogger->addAppender(fileAppender);
    //rootLogger->removeAppender('A1');
    //---------------- Log4cxx configuration-----------------------------------------------

  // Check file name
  
  if (argc < 2){
    //logger->info(_T("You have forgotten the file name."));
    cout << "You have forgotten the file name. \n";
    cout << "Try '-help' for more information. \n";
    exit(1);
  }  
  
  if (!strcmp(argv[1], "-help")){
        cout << "Usage: yoda FILE [OPTION] \n";
        cout << "\t -help               print this help and exit \n";
        cout << "\t -version            print version number \n";
        cout << "\t -p                  maximum number of packets to process [default all] \n";
        cout << "\t -multi            	generate multiple root files \n";
        cout << "\t -c            	set the compression level for the generated root file(s). Values: [0,9] [default = 3]\n";
        cout << "\t -o            	set the output directory for the generated root file(s). [default = $YODA_DATA]. Notice that in the same directory have to be prensent a log4cxx configuration file called \"log4cxx.conf\" \n";
        exit(1);
  }

  if (!strcmp(argv[1], "-version")){
        cout << "$Name: YODA6_3/05 $ $Revision: 6.3 $" << "\n";
        exit(1);
  }

  ifstream from (argv[1]);
  if (!from) {
    //logger->info(_T("The file does not exist."));
    cout << "The file does not exist. \n";
    exit(1);
  }  

  for (int i = 2; i < argc; i++){
    if (!strcmp(argv[i], "-p")){
        if (++i >= argc){
            cerr << "-p needs arguments. \n";
            cout << "Try '-help' for more information. \n";
            exit(1);
        }
        if (isdigit(*argv[i]) && (atoi(argv[i]) > 0)) {
            maxPackets = atoi(argv[i]);
        } else {
            //logger->info(_T("The file does not exist."));
            cerr << "-p needs a integer value. \n";
            cout << "Try '-help' for more information. \n";
            exit(1);
        }
        continue;
    }

    if (!strcmp(argv[i], "-multi")) multiFile = 1;

    if (!strcmp(argv[i], "-c")){
        if (++i >= argc){
            cerr << "-c needs arguments. \n";
            cout << "Try '-help' for more information. \n";
            exit(1);
        }
        if ((isdigit(*argv[i])) && ( (atoi(argv[i]) >= 0) && (atoi(argv[i]) <= 9))) {
            compression = atoi(argv[i]);
        } else {
            //logger->info(_T("The file does not exist."));
            cerr << "-c needs a integer value beetween 0 and 9. \n";
            cout << "Try '-help' for more information. \n";
            exit(1);
        }
        continue;
    }
    
    if (!strcmp(argv[i], "-o")){
        if (++i >= argc){
            cerr << "-o needs arguments. \n";
            cout << "Try '-help' for more information. \n";
            exit(1);
        }
        DIR* tempdir;
        if ((tempdir = opendir(argv[i])) != 0) {
            outDir = argv[i];
            closedir(tempdir);
        } else {
            //logger->info(_T("The file does not exist."));
            cerr << "-o needs an existing/accessable directory. \n";
            cout << "Try '-help' for more information. \n";
            exit(1);
        }
        continue;
    }
    
  }

  if (outDir == ""){
  	try {
    		outDir = getenv("YODA_DATA");
    		if (getenv("YODA_DATA") == NULL) throw NotFoundEnvironmentVarException("The variable YODA_DATA has not been found.");
  	} catch (NotFoundEnvironmentVarException exc) {
     		cout << "The variable YODA_DATA has not been found. \n";
     		cout << "Please check your environment variables \n";
     		oss.str("");
     		oss << exc.print();
     		logger->fatal(oss.str().c_str());
     		exit(1);
    	}
  }
  
    string pathDir(outDir);
    string pathLog = nomeFileLog;
    //Define the configuration file to be used on log4cxx
    PropertyConfigurator::configure(pathDir + "/log4cxx.conf");

    time_t rawtime;
    struct tm * timeinfo;
    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
    
    oss.str("");
    oss << "<-------------------------------START UNPACKING------------------------------->\n"
        << " Starting the program at: " << asctime (timeinfo) << " Opening file: " << argv[1];
    logger->info(oss.str().c_str());
  
  
  gROOT->SetBatch(kTRUE);
  EventReader *reader = new EventReader(maxPackets);

  int num = 0;
  TechmodelPamelaRun Run(argv[1], outDir, multiFile, compression);
  reader->Init(&Run);

   oss.str("");
   oss << "Init successul ok" << asctime (timeinfo);
   logger->debug(oss.str().c_str());

  reader->RunEvent(num); //TBD --- eliminate the runNumber
  reader->Finish();
  Run.WriteFiles();

  logger->info("<-------------------------------END UNPACKING------------------------------->\n");

  //Momentarly suspended the save   
  //system(command.c_str());
}

