#include "runnerDefine.icc"

#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

#include <iostream>

#include "UtlArguments.hh"
#include "DaqRunStart.hh"
#include "IlcRunStart.hh"
#include "RunControl.hh"
#include "ShmObject.hh"

using namespace std;

int main(int argc, const char **argv) {

  //unsigned eTime(CALICE_DAQ_TIME);
  //cout << argv[0] << " compiled at " << ctime((const time_t*)&eTime) << endl;
 
  UtlArguments argh(argc,argv);

  const bool useWrite(argh.option('w',true,"Make output file"));
  const bool useWriteAsc(argh.option('a',false,"Ascii output file"));
  const bool enableDisplays(argh.option('d',true,"Enable displays"));
  const bool doInterrupt(argh.option('i',true,"Interrupt runner"));
  const bool endlessRun(argh.option('z',false,"Do endless run"));
  
  const std::string type(argh.optionArgument('t',"crcNoise","Run type"));

#ifndef DAQ_ILC_TIMING
  unsigned v(DaqRunType::defaultVersion(DaqRunType::typeNumber(type)));
#else
  unsigned v(IlcRunType::defaultVersion(IlcRunType::typeNumber(type)));
#endif

  //const unsigned numberOfRuns(1);
  const unsigned numberOfRuns(argh.optionArgument('n',1,"Number of runs"));
  const unsigned printLevel(argh.optionArgument('p',9,"Print level"));
  const unsigned version(argh.optionArgument('v',v,"Run type version (type-dependent)"));
  
  const unsigned cfgLimit(argh.optionArgument('c',0x7fffffff,"Maximum number of configurations"));
#ifndef DAQ_ILC_TIMING
  const unsigned mode(argh.optionArgument('m',0,"Run type mode"));
  const unsigned acqLimit(argh.optionArgument('q',0x7fffffff,"Maximum number of acquisitions"));
  const unsigned evtLimit(argh.optionArgument('e',0x7fffffff,"Maximum number of events"));
#else
  const unsigned mode(0);
  const unsigned bntLimit(argh.optionArgument('b',0x7fffffff,"Maximum number of bunch trains"));
#endif
  const unsigned secLimit(argh.optionArgument('s',0x7fffffff,"Maximum time of run (secs)"));

  if(argh.help()) return 0;

  cout << "Command = " << argh.command() << endl << endl;
  
  if(!useWrite)   cout << "Dummy output selected" << endl;
  else {
    if(useWriteAsc) cout << "Ascii output selected" << endl;
    else            cout << "Binary output selected" << endl;
  }
  if(enableDisplays)  cout << "Display histogram filling enabled" << endl;
  else                cout << "Display histogram filling disabled" << endl;
  if(doInterrupt)   cout << "Runner interrupt selected" << endl;
  else              cout << "Runner interrupt not selected" << endl;
  
  cout << "Number of runs set to " << numberOfRuns << endl;
  cout << "Print level set to " << printLevel << endl;
  cout << "Run version set to " << version << endl;
  cout << "Run mode set to " << mode << endl;
  cout << "Run type set to " << type << endl;
  cout << endl;

#ifndef DAQ_ILC_TIMING
  DaqRunType rt(type,mode,version);
#else
  IlcRunType rt(type,mode,version);
#endif
  if(!rt.knownType()) {
    std::cerr << "Unknown run type" << std::endl;
    return 1;
  }

  std::cout << rt.typeComment() << std::endl;


  rt.printLevel(printLevel);
  rt.writeRun(useWrite);
  rt.ascWriteRun(useWriteAsc);
  rt.histogramRun(enableDisplays);
  rt.endlessRun(endlessRun);

#ifndef DAQ_ILC_TIMING
  DaqRunStart rs;
  rs.runType(rt);
  rs.maximumNumberOfAcquisitionsInRun(acqLimit);
  rs.maximumNumberOfEventsInRun(evtLimit);
#else
  IlcRunStart rs;
  rs.runType(rt);
  rs.maximumNumberOfBunchTrainsInRun(bntLimit);
#endif
  rs.maximumNumberOfConfigurationsInRun(cfgLimit);
  rs.maximumTimeOfRun(UtlTimeDifference(secLimit-1,999999));

  ShmObject<RunControl> shmRunControl(RunControl::shmKey);
  RunControl *pRc(shmRunControl.payload());
  if(pRc==0) {
    std::cerr << "Cannot connect to run control shared memory" << std::endl;
    return 2;
  }

  pRc->numberOfRuns(numberOfRuns);
  pRc->runStart(rs);
  //if(doInterrupt) pRc->flag(RunControl::runEnd);
  if(doInterrupt) pRc->flag(RunControl::sequenceEnd);
  //if(doInterrupt) pRc->runInterrupt(SIGINT);

  pRc->print(cout);  

  return 0;
}
