/*
  This file is part of CDO. CDO is a collection of Operators to manipulate and analyse Climate model Data.

  Author: Uwe Schulzweida

*/

#ifndef CDO_TIMER_H
#define CDO_TIMER_H

#include <chrono>

namespace cdo
{

using namespace std::chrono;
using clock = steady_clock;

class timer
{
public:
  timer() { reset(); }

  void
  reset()
  {
    m_start = clock::now();
  }

  double
  time_span()
  {
    auto timeSpan = duration_cast<duration<double>>(clock::now() - m_start);
    return timeSpan.count();
  }

  double
  elapsed(bool resetTimer = false)
  {
    auto timeSpan = time_span();
    if (resetTimer) reset();
    return timeSpan;
  }

private:
  clock::time_point m_start;
};

// interval timer (stop watch)
class itimer
{
public:
  itimer() {}

  void
  start()
  {
    m_running = true;
    m_start = clock::now();
  }

  void
  stop()
  {
    m_stop = clock::now();
    m_running = false;
  }

  double
  time_span()
  {
    if (m_running) stop();
    auto timeSpan = duration_cast<duration<double>>(m_stop - m_start);
    return timeSpan.count();
  }

  double
  elapsed()
  {
    return time_span();
  }

private:
  clock::time_point m_start;
  clock::time_point m_stop;
  bool m_running = false;
};

inline double
get_wtime()
{
  return duration_cast<duration<double>>(clock::now().time_since_epoch()).count();
}

}  // namespace cdo

#endif /* CDO_TIMER_H */
