#ifndef _PIUMA_LOGGER_H_
#define _PIUMA_LOGGER_H_

#include "../lib/types.h"
#include "../lib/queue.h"


typedef u8 LogLevel;
#define LOG_ERROR     0
#define LOG_WARNING  50
#define LOG_INFO    100
#define LOG_DEBUG   150

struct LogSourceInfo
{
	const char *filename;
	u32 line;
	const char *function;
};

typedef u64 LogId;
struct LogEntry
{
	LogLevel level;
	char *message;

	LogId id;
	LogSourceInfo source;
};

struct Logger
{
	QUEUE_TYPE(struct LogEntry) message_queue = NULL;

	LogId last_id = 0;
	u64 overflow_count = 0; // Number of times the buffer was full, but we added a message anyway removing the oldest one
};

void Logger_Init(struct Logger *logger);
void Logger_Deinit(struct Logger *logger);

void Logger_Clear(struct Logger *logger);
void Logger_AddMessage(struct Logger *logger, LogSourceInfo source_info, LogLevel level, const char *format_message, ...);
void Logger_RemoveOldestMessage(struct Logger *logger);

u64 Logger_MessageCount(struct Logger *logger);
struct LogEntry *Logger_MessageAt(struct Logger *logger, u64 index);


extern struct Logger global_logger;


#define LOG_INIT()          Logger_Init(&global_logger)
#define LOG_DEINIT()        Logger_Deinit(&global_logger)
#define LOG_CLEAR()         Logger_Clear(&global_logger)
#define LOG(level, /*format_message,*/ ...) Logger_AddMessage(&global_logger, LogSourceInfo{.filename = __FILE__, .line = __LINE__, .function = __func__}, level, /*format_message,*/ __VA_ARGS__)


#endif
