#pragma once
#include "Deer/Tools/Memory.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"

namespace spdlog {
	class logger;
}

// Simple file to define logs functions optimized depending on the compilation

namespace Deer {
	class Log {
	  public:
		static void init();
		static void shutdown();

		static void coreTrace(const char* msg);

		static inline Ref<spdlog::logger>& getCoreLogger() {
			return coreLogger;
		}
		static inline Ref<spdlog::logger>& getClientLogger() {
			return clientLogger;
		}
		static inline Ref<spdlog::logger>& getScriptLogger() {
			return scriptLogger;
		}
		static inline Ref<spdlog::logger>& getEditorEngineLogger() {
			return EditorEngineLogger;
		}

	  private:
		static Ref<spdlog::logger> coreLogger;
		static Ref<spdlog::logger> clientLogger;
		static Ref<spdlog::logger> scriptLogger;
		static Ref<spdlog::logger> EditorEngineLogger;
	};
} // namespace Deer

#define DEER_CORE_TRACE(...) Deer::Log::getCoreLogger()->trace(__VA_ARGS__)
#define DEER_CORE_INFO(...) Deer::Log::getCoreLogger()->info(__VA_ARGS__)
#define DEER_CORE_WARN(...) Deer::Log::getCoreLogger()->warn(__VA_ARGS__)
#define DEER_CORE_ERROR(...) Deer::Log::getCoreLogger()->error(__VA_ARGS__)

#define DEER_SCRIPT_TRACE(...) Deer::Log::getScriptLogger()->trace(__VA_ARGS__)
#define DEER_SCRIPT_INFO(...) Deer::Log::getScriptLogger()->info(__VA_ARGS__)
#define DEER_SCRIPT_WARN(...) Deer::Log::getScriptLogger()->warn(__VA_ARGS__)
#define DEER_SCRIPT_ERROR(...) Deer::Log::getScriptLogger()->error(__VA_ARGS__)

#define DEER_EDITOR_ENGINE_TRACE(...) Deer::Log::getEditorEngineLogger()->trace(__VA_ARGS__)
#define DEER_EDITOR_ENGINE_INFO(...) Deer::Log::getEditorEngineLogger()->info(__VA_ARGS__)
#define DEER_EDITOR_ENGINE_WARN(...) Deer::Log::getEditorEngineLogger()->warn(__VA_ARGS__)
#define DEER_EDITOR_ENGINE_ERROR(...) Deer::Log::getEditorEngineLogger()->error(__VA_ARGS__)

#ifdef LINUX
#define DEER_CORE_ASSERT(condition, ...)                \
	if (!(condition)) {                                 \
		Deer::Log::getCoreLogger()->error(__VA_ARGS__); \
		__builtin_trap();                               \
	}
#define DEER_SCRIPT_ASSERT(condition, ...)                \
	if (!(condition)) {                                   \
		Deer::Log::getScriptLogger()->error(__VA_ARGS__); \
	}
#endif
#ifdef WINDOWS
#define DEER_CORE_ASSERT(condition, ...)                \
	if (!(condition)) {                                 \
		Deer::Log::getCoreLogger()->error(__VA_ARGS__); \
		__debugbreak();                                 \
	}
#define DEER_SCRIPT_ASSERT(condition, ...)                \
	if (!(condition)) {                                   \
		Deer::Log::getScriptLogger()->error(__VA_ARGS__); \
		__debugbreak();                                   \
	}
#endif
