
#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"
#include "style/mirage_style.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;
	std::ostream* output_stream;

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

	/* 打印格式化的日志消息到相应的流 */
	std::println(*output_stream, "sokol_gfx: [{}][{}][ID:{}][{}:{}] {}", 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();
		if (!mirage_style::get().load_config("default_style.toml")) {
			std::println(std::cerr, "mirage: 无法加载样式配置");
		}
		render_context = mirage_create_render_context();
		render_context->init();
		sg_desc desc = {};
		desc.logger  = {
			.func = mirage_log,
			.user_data = nullptr
		};
		desc.environment = render_context->get_environment();
		sg_setup(desc);
		render_context->end_init();
	}
	// 初始化用时
	std::println(std::cout, "mirage: 初始化耗时 {} ms", std::chrono::duration_cast<std::chrono::milliseconds>(duration).count());
}

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();
}
