#include "Timer.h"

namespace core
{

   Timer::Timer(EPoll &ePoll, double delay = 0.0f) : Socket(ePoll, "Timer")
   {
      setDescriptor(timerfd_create(CLOCK_REALTIME, 0));
      setTimer(delay);
   }

   Timer::~Timer()
   {
   }

   void Timer::setTimer(double delay)
   {

      double integer;
      double fraction;
      struct itimerspec timer;

      delayValue = delay;

      timer.it_interval.tv_sec = 0;
      timer.it_interval.tv_nsec = 0;

      fraction = modf(delay, &integer);

      timer.it_value.tv_sec = (int)integer;
      timer.it_value.tv_nsec = (int)(fraction * 1000000000);

      timerfd_settime(getDescriptor(), 0, &timer, NULL);
   }

   void Timer::clearTimer()
   {

      struct itimerspec timer;

      timer.it_interval.tv_sec = 0;
      timer.it_interval.tv_nsec = 0;
      timer.it_value.tv_sec = 0;
      timer.it_value.tv_nsec = 0;

      timerfd_settime(getDescriptor(), 0, &timer, NULL);
   }

   double Timer::getElapsed()
   {
      struct itimerspec timer;
      timerfd_gettime(getDescriptor(), &timer);
      double toTimeout = (double)((timer.it_value.tv_sec * 1000000000L) + timer.it_value.tv_nsec) / 1000000000L;
      return delayValue - toTimeout;
   }

   void Timer::onDataReceived(std::string data)
   {
      onTimeout();
   }

   double Timer::getEpoch()
   {
      return (double)std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count() / 1000000000L;
   }

}
