#include <string>
#include <iostream>
#include <limits>

#include "TRandom3.h"
#include "TTimeStamp.h"

#include "km3net-dataformat/online/JDAQClock.hh"
#include "km3net-dataformat/online/JDAQUTCExtended.hh"

#include "JMath/JRandom.hh"
#include "JDAQ/JDAQToolkit.hh"

#include "Jeep/JParser.hh"
#include "Jeep/JMessage.hh"


/**
 * \file
 *
 * Auxiliary program to test I/O of KM3NETDAQ::JDAQUTCExtended with random data.
 * \author mdejong
 */
int main(int argc, char **argv)
{
  using namespace std;
  using namespace JPP;
  using namespace KM3NETDAQ;

  Long64_t numberOfEvents;
  double   precision;
  UInt_t   seed;
  int      debug;

  try { 

    JParser<> zap("Auxiliary program to test UTC times with random data.");
    
    zap['n'] = make_field(numberOfEvents)      = 10;
    zap['e'] = make_field(precision)           = JDAQUTCExtended::getTick();
    zap['S'] = make_field(seed)                = 0;
    zap['d'] = make_field(debug)               = 3;
    
    zap(argc, argv);
  }
  catch(const exception &error) {
    FATAL(error.what() << endl);
  }


  gRandom->SetSeed(seed);


  ASSERT(numberOfEvents > 0);

  for (Long64_t counter = 0; counter <= numberOfEvents; ++counter) {

    timespec   t0;

    t0.tv_sec  = getRandom<time_t>((time_t) getFrameTime(), numeric_limits<Int_t>::max());
    t0.tv_nsec = getRandom<long>  (0, (long) (1.0e9 - 1.0));


    TTimeStamp t1;

    t1.SetSec    ((Int_t) t0.tv_sec);
    t1.SetNanoSec((Int_t) t0.tv_nsec);


    double tev = getRandom<double>(0.0, getFrameTime());

    JDAQUTCExtended utc = getDAQUTCExtended(t1,  tev);
    TTimeStamp      ts  = getTimeStamp     (utc, tev);

    double t0_ns  = (double) t0.tv_sec   * 1.0e9  +  (double) t0.tv_nsec;
    double ts_ns  = (double) ts.GetSec() * 1.0e9  +  (double) ts.GetNanoSec();

    DEBUG("t0_ns  " << FIXED(30,0) << t0_ns  << endl);
    DEBUG("ts_ns  " << FIXED(30,0) << ts_ns  << endl);

    ASSERT(fabs(t0_ns - ts_ns) <= precision);
  }
  
  return 0;
}