#include "runnerDefine.icc"

#include <iostream>
#include <sstream>

#include "RcdArena.hh"
#include "UtlArguments.hh"
#include "UtlPack.hh"
#include "UtlPrintHex.hh"
#include "EmcStageReadout.hh"
#include "DuplexSocket.hh"
#include "SubAccessor.hh"

using namespace std;

int main(int argc, const char **argv) {
  UtlArguments argh(argc,argv);
  argh.print(cout);
  //const unsigned runNumber(argh.lastArgument(999999));
  
  /*
  unsigned _dataOut[2];
  unsigned _dataIn[1024],nIn(10);
  EmcStageStartupData *p((EmcStageStartupData*)_dataIn);

  _dataOut[0]=0x5041554c;
  //_dataOut[1]=(sizeof(EmcStageStartupData)+3)/4;
  _dataOut[1]=0x00003130;
  //_dataOut[1]=123;
  int nBytes(8);

  UtlPack _packOut[2];
  _packOut[0].byte(0,0x50);
  _packOut[0].byte(1,0x41);
  _packOut[0].byte(2,0x55);
  _packOut[0].byte(3,0x4c);
  _packOut[1].byte(0,0x30);
  _packOut[1].byte(1,0x30);
  _packOut[1].byte(2,0x31);
  _packOut[1].byte(3,0x30);

  bool flip(true);
  cout << "About to send..." << std::endl;
  if(!flip) {
    cout << " " << printHex(_dataOut[0]) << std::endl;
    cout << " " << printHex(_dataOut[1]) << std::endl;
  } else {
    cout << " " << printHex(_packOut[0].word()) << std::endl;
    cout << " " << printHex(_packOut[1].word()) << std::endl;
  }
  //p->print(cout);

  DuplexSocket _socket("134.158.90.89",1200,10);

  std::cout << "About to write to socket..." << std::endl;

  const char *pout(0);
  if(!flip) pout=(const char*)_dataOut;
  else      pout=(const char*)_packOut;

  if(!_socket.send(pout,nBytes)) {
    std::cerr << "Error writing to socket; number of bytes written < "
	      << nBytes << std::endl;
    perror(0);
    
  } else {
    std::cout << "Written; about to read from socket..." << std::endl;

    int n(-1);
    n=_socket.recv((char*)_dataIn,4);
    if(n!=4) {
      std::cerr << "Error reading from socket; number of bytes written = "
		<< n << " < " << 4 << std::endl;
      perror(0);
    } else {
      std::cout << "Read " << printHex(_dataIn[0]) << std::endl;

      n=_socket.recv((char*)(_dataIn+1),4*(nIn-1));
      if(n!=(int)4*(nIn-1)) {
	std::cerr << "Error reading from socket; number of bytes written = "
		  << n << " < " << 4*(nIn-1) << std::endl;
	perror(0);
      } else {
	for(unsigned i(0);i<nIn;i++) {
	  cout << "Word " << i << " = " << printHex(_dataIn[i]) << endl;
	}
	p->print(cout);
      }
    }
  }
  */

  RcdArena arena;
  arena.recordType(RcdHeader::startUp);
  SubAccessor accessor(arena);

  //EmcStageReadout esr("192.76.172.67");
  //EmcStageReadout esr("131.169.184.238");
  EmcStageReadout esr(EMC_STAGE_SKT);
  esr.printLevel(255);

  while(true) {
    // arena.updateRecordTime();
    //arena.deleteData();
    arena.initialise(RcdHeader::runStart);
    esr.good();
    assert(esr.record(arena));
    
    std::vector<const EmcStageRunData*>
      v(accessor.extract<EmcStageRunData>());
    assert(v.size()==1);

    //    if(v[0]->surveillanceCounter()==123) {
    if(v[0]->headerError() || !v[0]->validateChecksum()) {
      arena.RcdHeader::print(cout);
      v[0]->print(cout);
    }

    sleep(10);
    
    /*    
    arena.updateRecordTime();
    arena.deleteData();
    esr.bad();
    esr.record(arena);

    std::vector<const EmcStageRunData*>
      w(accessor.extract<EmcStageRunData>());
    assert(w.size()==1);

    //    if(w[0]->surveillanceCounter()==123) {
    if(!w[0]->headerError()) {
      arena.RcdHeader::print(cout);
      w[0]->print(cout);
    }
    
    sleep(60);
    */
  }

  cout << endl << "END OF MAIN" << endl << endl;
  return 0;
}
