#include <chrono>

#include <PerfTimeline/PerfTimeline.hpp>

PerfTimeline::Event::Event(PerfTimeline &timeline) : timeline(timeline) {}

void PerfTimeline::Event::start()
{
    startTime = std::chrono::steady_clock::now() - timeline.startPoint;
    threadStartTime = timeline.threadClock.getDuration();
}

void PerfTimeline::Event::end()
{
    std::chrono::steady_clock::duration endTime = std::chrono::steady_clock::now() - timeline.startPoint;
    ThreadClock::Duration threadEndTime = timeline.threadClock.getDuration();

    intervalList.push_back(PerfTimeline::Interval{startTime, endTime, threadStartTime, threadEndTime});
}

void PerfTimeline::Event::reset()
{
    intervalList.clear();
}

const std::vector<PerfTimeline::Interval>& PerfTimeline::Event::intervals() const
{
    return intervalList;
}

PerfTimeline::PerfTimeline() :
    #define DECL_PERF_EVENT(name, ...) name(*this),
    #include <PerfTimeline/PerfEventList.hpp>
    ignore(0)
{}

void PerfTimeline::reset()
{
#ifndef NO_PERF_TIMERS
    startPoint = std::chrono::steady_clock::now();
    threadClock.reset();

    #define DECL_PERF_EVENT(name, ...) name.reset();
    #include <PerfTimeline/PerfEventList.hpp>
#endif
}

PerfTimeline::Ticks PerfTimeline::getCurrentDuration()
{
    return std::chrono::steady_clock::now() - startPoint;
}