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

#include <iostream>

#include "UtlArguments.hh"
#include "RcdArena.hh"
#include "RcdIoSkt.hh"
#include "CrcReadout.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);
  
  UtlArguments argh(argc,argv);
  
  const unsigned pciCard(argh.optionArgument('p',1,"PCI card"));
  const unsigned crate(argh.optionArgument('c',0xec,"Crate"));
  
  if(argh.help()) return 0;
  
  cout << "PCI card set to " << pciCard << endl;
  cout << "Crate set to 0x" << hex << crate << dec << endl;
  
  RcdIoSkt s;
  CrcReadout c(pciCard,crate);
  c.printLevel(4);

  RcdArena r;
  r.initialise(RcdHeader::startUp);
  
  assert(s.open(1124+pciCard));
  while(r.recordType()!=RcdHeader::shutDown) {
    
    // Read next record from socket
    assert(s.read(r));
    
    // Check for startUp record
    if(r.recordType()==RcdHeader::startUp) {
      
      // Put in software information
      SubInserter inserter(r);
      DaqSoftware *dsw(inserter.insert<DaqSoftware>(true));
      dsw->message(argh.command());
      dsw->setVersions();
      dsw->print(std::cout);
    }
    
    // Check for runStart record
    if(r.recordType()==RcdHeader::runStart) {

      // Access the DaqRunStart to get print level
      SubAccessor accessor(r);
      std::vector<const DaqRunStart*> v(accessor.extract<DaqRunStart>());
      if(v.size()>0)  c.printLevel(v[0]->runType().printLevel());
    }

    // Process record and send back
    assert(c.record(r));
    assert(s.write(r));
  }

  assert(s.close());

  return 0;
}
