#pragma once

#include <string>
#include <source_location>
#include <format>

namespace Log
{

	enum class Level
	{
		Info,
		Warning,
		Error,
		Debug,
		VkValidation,
		DeviceSetup
	};

	// void Message(Level Level, const std::source_location& Location = std::source_location::current(), const std::string& Message);
	void Message(Level Level, const std::string& Message, const std::source_location& Location);

	template <typename... Args>
	void Info(const std::string& Format, Args&&... Arguments, const std::source_location& Location = std::source_location::current())
	{
		Message(Level::Info, std::vformat(Format, std::make_format_args(Arguments...)), Location);
	}

	template <typename... Args>
	void Warning(const std::string& Format, Args&&... Arguments, const std::source_location& Location = std::source_location::current())
	{
		Message(Level::Warning, std::vformat(Format, std::make_format_args(Arguments...)), Location);
	}

	template <typename... Args>
	void Error(const std::string& Format, Args&&... Arguments, const std::source_location& Location = std::source_location::current())
	{
		Message(Level::Error, std::vformat(Format, std::make_format_args(Arguments...)), Location);
	}

	template <typename... Args>
	void Debug(const std::string& Format, Args&&... Arguments, const std::source_location& Location = std::source_location::current())
	{
		Message(Level::Warning, std::vformat(Format, std::make_format_args(Arguments...)), Location);
	}

	template <typename... Args>
	void Validation(const std::string& Format, Args&&... Arguments, const std::source_location& Location = std::source_location::current())
	{
		Message(Level::VkValidation, std::vformat(Format, std::make_format_args(Arguments...)), Location);
	}

	template <typename... Args>
	void DeviceSetup(const std::string& Format, Args&&... Arguments, const std::source_location& Location = std::source_location::current())
	{
		Message(Level::DeviceSetup, std::vformat(Format, std::make_format_args(Arguments...)), Location);
	}
} // namespace Log
