/*
 * Mirai. Copyright (C) 2024 Vyn
 * This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
 * The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
 */

#ifndef CPP_UTILS_DEBUG_H
#define CPP_UTILS_DEBUG_H

#include <algorithm>
#include <chrono>
#include <iostream>
#include <ostream>
#include <string>

namespace cpputils::debug
{

class Timer
{
  public:
	Timer() : startTime(std::chrono::steady_clock::now())
	{
	}

	void start()
	{
		startTime = std::chrono::steady_clock::now();
		isRunning = true;
	}

	void stop()
	{
		const auto now = std::chrono::steady_clock::now();
		duration += std::chrono::duration_cast<std::chrono::milliseconds>(now - startTime).count();
		isRunning = false;
	}

	void reset()
	{
		duration = 0;
		isRunning = false;
	}

	void printTimeElapsed(const std::string &message) const
	{
		long durationToShow = duration;
		if (isRunning) {
			const auto now = std::chrono::steady_clock::now();
			durationToShow +=
				std::chrono::duration_cast<std::chrono::milliseconds>(now - startTime).count();
		}
		std::cout << "[Debug - Timer] " << message << ": " << durationToShow << " ms" << std::endl;
	}

  private:
	std::chrono::time_point<std::chrono::steady_clock, std::chrono::nanoseconds> startTime;

	// Timer are always running when created. You can use .reset() after creation.
	bool isRunning = true;
	long duration = 0;
};
} // namespace cpputils::debug

#endif
