#ifndef jf_profiler_h
#define jf_profiler_h

#include <map>
#include <mutex>
#include <thread>

#include "MapConfig.h"
#include "Timer.h"
#include "Utils.h"

namespace jf {

/**
 * @brief 每interval时间打印一次各个recored的平均时间
 *
 */
class Profiler {
   public:
    static void run() {
        auto tm = []() { Timer::StartLoop(); };
        std::thread t(tm);
        t.detach();
    }

    static std::mutex m;
    static void Loop(double deltaInSecond) {
        return;
        // accTime = accTime + deltaInSecond;
        // double thisInterval = accTime - lastStatTime;
        // if (thisInterval >= interval) {
        //     std::lock_guard<std::mutex> lk(m);
        //     for (auto& [_, record] : records) {
        //         double accDuration = Timer::AsMilliseconds(record.accDurationSinceLastStat);
        //         // 执行这个profiler平均时间
        //         double average = accDuration / record.execNumSinceLastStat;
        //         // jf_log_profiler(
        //         //   "Profiler:{0}  cost:{1}\% time:{2:.5f} execNum:{3} frame:{4}",
        //         //   record.profilerName,
        //         //   accDuration / (thisInterval * 10.0),  // 这里转化为100%了所以*10
        //         //   average,
        //         //   record.execNumSinceLastStat,
        //         //   record.execNumSinceLastStat / accDuration * 1000
        //         //   );

        //         record.execNumSinceLastStat = 0;
        //         record.accDurationSinceLastStat = timeDuration();
        //     }
        //     lastStatTime = accTime;
        // }
    }

    static void Start(const std::string& profilerName) {
        return;
        if (!inited) {
            Timer::RegistLoopFunc(Profiler::Loop);
            interval = MapConfig::profiler_interval;
            std::cout << MapConfig::profiler_interval;
            inited = true;
        }
        if (!jf::Utils::Contains(records, profilerName))
            records[profilerName] = {profilerName, Timer::Now(), timeDuration(), 0};
        else {
            records[profilerName].lastStart = Timer::Now();
        }
    }
    static void End(const std::string& profilerName) {
        return;
        assert(Utils::Contains(records, profilerName));
        Record& r = records[profilerName];
        r.accDurationSinceLastStat += Timer::Now() - r.lastStart;
        r.execNumSinceLastStat++;
    }

   private:
    struct Record {
        std::string profilerName;               // 记录名称
        timePoint lastStart;                    // 最近一次begin开始时间
        timeDuration accDurationSinceLastStat;  // 总执行时间
        int execNumSinceLastStat;               // 执行了多少次
    };
    static std::map<std::string, Record> records;
    static double accTime;
    static double lastStatTime;
    static bool inited;
    static int interval;
};

}  // namespace jf

#endif