#pragma once

#include <string>
#include <vector>
#include <map>
#include <chrono>
#include "Jikan.h"

#ifdef INCLUDE_GPU_TIMER
    #include <cuda_runtime.h>
#endif

typedef std::chrono::steady_clock::time_point chrono_time_type;

class EventData{
public:

#ifdef INCLUDE_GPU_TIMER
    cudaEvent_t gpu_start, gpu_end;
#endif

    bool if_mode_set; // If measurment type (MPI, OpenMP ...) is set
    bool ifCUDAinit;  // If CUDA variables are initialized
    bool ifStart, ifEnd; // If measurment for current code block is started/finished 
    double elapsed_time, double_start;               // seconds
    double ContiniousTime;
    int count; // Count of current code block measurments
    chrono_time_type start;
    std::vector<double> time_series; // Measurments time series for current code block
    std::string event_name; // Name ID for current code block
    std::vector<bool> mode; // Measurment type for current code block. Order: mode[0] ~ if MPI, mode[1] ~ if OpenMP, mode[2] ~ if CUDA

    EventData();
    ~EventData();
    EventData(const std::string& name);
    EventData& operator=(const EventData& src);

    double GetMeanElapsedTime(); // elapsed_time / count for each measuring code block
    void GetModeVals(const int& mode); // 
    std::string GetEventModeName();    // Generate measure type for current code block (used for dump), for example "MPI", "MPI_OpenMP" etc. 

private:
    void InitEventsCUDA();
    void DeinitEventsCUDA();

    // void MPISync();
    // void OpenMPSync();
    // void CUDASyncStart();
    // void CUDASyncEnd();
};