
#include "mirage.h"

#include <iostream>
#include <thread>

#include "font/font_system.h"
#include "window/mwindow.h"
#include "misc/mirage_scoped_duration_timer.h"
#include "platform_window/platform_window.h"

void mirage_log(const char* tag, uint32_t        log_level, uint32_t     log_item_id, const char* message_or_null,
                uint32_t    line_nr, const char* filename_or_null, void* user_data) {
	/* 处理NULL指针情况 */
	const char* tag_str  = tag ? tag : "(null)";
	const char* msg_str  = message_or_null ? message_or_null : "(no message)";
	const char* file_str = filename_or_null ? filename_or_null : "(unknown)";

	/* 根据log_level确定日志级别字符串和输出流 */
	const char* level_str;
	FILE*       output_stream;

	switch (log_level) {
		case 0:
			level_str = "PANIC";
			output_stream = stderr;
			break;
		case 1:
			level_str = "ERROR";
			output_stream = stderr;
			break;
		case 2:
			level_str = "WARNING";
			output_stream = stderr;
			break;
		case 3:
			level_str = "INFO";
			output_stream = stdout;
			break;
		default:
			level_str = "UNKNOWN";
			output_stream = stderr; // 默认使用stderr
			break;
	}

	/* 打印格式化的日志消息到相应的流 */
	fprintf(output_stream, "[%s][%s][ID:%u][%s:%u] %s\n", tag_str, level_str, log_item_id, file_str, line_nr, msg_str);

	/* 在此实现中未使用user_data */
	(void) user_data;
}


void mirage_app::init() {
	duration_type duration;
	{
		mirage_scoped_duration_timer timer(duration);

		last_time = get_current_time();
		render_context = mirage_create_render_context();
		render_context->init();
		const sg_desc desc = {
			.logger = {
				.func = mirage_log,
				.user_data = nullptr
			},
			.environment = render_context->get_environment(),
		};
		sg_setup(desc);
		render_context->end_init();
	}
	// 初始化用时
	std::cout << "mirage: " << "Initialization took " << std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() << "ms" << std::endl;
}


void mirage_app::run() {
	while (!platform_window::get_windows().empty()) {
		delta_time = get_current_time() - last_time;
		platform_window::poll_events();

		for (const auto& window: mwindow::get_all()) {
			if (const auto shared_window = window.lock()) {
				shared_window->update();
			}
		}

		last_time = get_current_time();
		std::this_thread::sleep_for(std::chrono::milliseconds(1));
	}
	running = false;
	texture_sampler_builder::clear();
	render_context->cleanup();
	delete render_context;
	font_manager::instance().destroy();
}
