#pragma once
#include "common.hpp"
#include <time.h>
#include <set>


#ifdef STATS
class Timer {
    private:
        static std::set<Timer*> registry;
        char name[32];
        struct timespec sum, curr; // TODO: maintain a max

    public:
        Timer(const char*, bool=false);
        ~Timer();
        void reset();
        uint64_t get() const;
        void start();
        void end();
        void print() const;
        static void print_all();
        static void reset_all();
};
#else
class Timer {
    public:
        INLINE Timer(const char*, bool=false) {}
        INLINE void reset() {}
        INLINE uint64_t get() const { return 0; }
        INLINE void start() {}
        INLINE void end() {}
        INLINE void print() const {}
        INLINE static void print_all() {}
        INLINE static void reset_all() {}
};
#endif


#ifdef STATS
class Counter {
    private:
        static std::set<Counter*> registry;
        char name[32];
        long long unsigned num, sum;

    public:
        Counter(const char*, bool=false);
        ~Counter();
        void reset();
        void inc();
        void inc(unsigned);
        void print() const;
        static void print_all();
        static void reset_all();
};
#else
class Counter {
    public:
        INLINE Counter(const char*, bool=false) {}
        INLINE void reset() {}
        INLINE void inc() {}
        INLINE void inc(unsigned) {}
        INLINE void print() const {}
        INLINE static void print_all() {}
        INLINE static void reset_all() {}
};
#endif