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

#include <iostream>
#include <sstream>
#include <vector>
#include <cstdio>

#include "UtlTime.hh"
#include "UtlArguments.hh"
#include "RcdArena.hh"
#include "RcdWriterAsc.hh"

#include "DaqRunStart.hh"
#include "RcdReaderAsc.hh"
#include "RcdReaderBin.hh"
#include "RunReader.hh"

#include "ChkCount.hh"
#include "ChkPrint.hh"

using namespace std;


int main(int argc, const char **argv) {
  UtlArguments argh(argc,argv);
  //argh.print(cout);

  //const bool useReadAsc(argh.option('a',"Ascii input file"));
  //const bool slwRead(argh.option('s',"Slow data input file"));
  const unsigned numberOfRecords(argh.optionArgument('r',0x7fffffff,"Number of records"));
  const unsigned vnum(argh.lastArgument(999999));

  if(argh.help()) return 0;

  /*
  ostringstream sout;
  sout << vnum;

  RcdReader *reader(0);
  if(useReadAsc) reader=new RcdReaderAsc();
  else           reader=new RcdReaderBin();

  if(slwRead) assert(reader->open(std::string("data/slw/Slw")+sout.str()));
  else        assert(reader->open(std::string("data/run/Run")+sout.str()));
  */
  RunReader *reader(new RunReader);
  reader->open(vnum);

  RcdArena arena;
  ChkCount ct;
  ChkPrint hn;

  // This enables printing of all subrecord headers, but not their data
  //hn.enableSubrecords(true);

  // This enables printing of all record headers
  //hn.enableType(true);

  // These enable/disable printing of particular types of record headers
  //hn.enableType(RcdHeader::startUp,true);
  //hn.enableType(RcdHeader::slowControl,true);
  //hn.enableType(RcdHeader::slowReadout,true);
  //hn.enableType(RcdHeader::configurationStart,true);
  //hn.enableType(RcdHeader::configurationStop,true);
  //hn.enableType(RcdHeader::configurationEnd,true);
  hn.enableType(RcdHeader::trigger,false);
  hn.enableType(RcdHeader::event,false);

  // This enables printing of all subrecord data
  //hn.enable(true);

  // These enable printing of groups of subrecord data
  //hn.enable(SubHeader::daq,true);
  //hn.enable(SubHeader::crc,true);
  //hn.enable(SubHeader::emc,true);
  //hn.enable(SubHeader::ahc,true);
  //hn.enable(SubHeader::trg,true);

  // These enable/disable printing of particular types of subrecord data
  //hn.enable(subRecordType<DaqRunEndV0>(),true);
  //hn.enable(subRecordType<DaqRunEnd>(),true);
  //hn.enable(subRecordType<DaqEvent>(),false);

  //hn.enable(subRecordType< CrcLocationData<CrcAdm1025StartupData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcAdm1025SlowControlsData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcAdm1025SlowReadoutData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcLm82StartupData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcLm82SlowControlsData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcLm82SlowReadoutData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcBeRunData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcBeEventDataV0> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcBeEventData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcBeTrgRunData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcFeConfigurationData> >(),true);
  //hn.enable(subRecordType< CrcLocationData<CrcVlinkEventData> >(),true);

  //hn.enable(subRecordType< CrcLocationData<EmcFeConfigurationData> >(),true);
  
  //hn.enable(subRecordType< MpsLocationData<MpsUsbDaqBunchTrainData> >(),true);
  hn.enable(subRecordType< MpsLocationData<MpsSensor1BunchTrainData> >(),true);

  //hn.enable(subRecordType<BmlLc1176RunData>(),true);
  //hn.enable(subRecordType<BmlLc1176ConfigurationData>(),true);
  //hn.enable(subRecordType<BmlLc1176EventData>(),true);

  unsigned i(0);
  while(reader->read(arena) && i<numberOfRecords) {
    ct.record(arena);
    hn.record(arena);
    i++;
  }

  ct.print(cout);

  reader->close();
  delete reader;
}
