#include "ML_Log.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

ML_Log::ML_Log()
	:m_bInit(false)
{

}

ML_Log::~ML_Log()
{
	if (m_bInit)
	{
		this->UnInit();
	}
}

bool ML_Log::Init(const char* nFileName, const int nMaxFileSize, const int nMaxFile,
	const OutMode outMode, const OutPosition outPos, const OutLevel outLevel)
{
	if (m_bInit)
	{
		printf("It's already initialized\n");
		return false;
	}
	m_bInit = true;

	try
	{
		const char* pFormat = "[%Y-%m-%d %H:%M:%S.%e] <thread %t> [%^%l%$]\n[%@,%!]\n%v\n";
		//sinkÈÝÆ÷
		std::vector<spdlog::sink_ptr> vecSink;

		//¿ØÖÆÌ¨
		if (outPos & CONSOLE)
		{
			auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
			//console_sink->set_level(spdlog::level::trace);
			console_sink->set_pattern(pFormat);
			vecSink.push_back(console_sink);
		}

		//Îļþ
		if (outPos & FILE)
		{
			auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(nFileName, nMaxFileSize, nMaxFile);
			//file_sink->set_level(spdlog::level::trace);
			file_sink->set_pattern(pFormat);
			vecSink.push_back(file_sink);
		}

		//ÉèÖÃloggerʹÓöà¸ösink
		if (outMode == ASYNC)//Òì²½
		{
			spdlog::init_thread_pool(102400, 1);
			auto tp = spdlog::thread_pool();
			m_pLogger = std::make_shared<spdlog::async_logger>(LOG_NAME, begin(vecSink), end(vecSink), tp, spdlog::async_overflow_policy::block);
		}
		else//ͬ²½
		{
			m_pLogger = std::make_shared<spdlog::logger>(LOG_NAME, begin(vecSink), end(vecSink));
		}
		m_pLogger->set_level((spdlog::level::level_enum)outLevel);

		//Óöµ½warn¼¶±ð£¬Á¢¼´flushµ½Îļþ
		m_pLogger->flush_on(spdlog::level::warn);
		//¶¨Ê±flushµ½Îļþ£¬Ã¿ÈýÃëË¢ÐÂÒ»´Î
		spdlog::flush_every(std::chrono::seconds(3));
		spdlog::register_logger(m_pLogger);
	}
	catch (const spdlog::spdlog_ex& ex)
	{
		std::cout << "Log initialization failed: " << ex.what() << std::endl;
		return false;
	}
	return true;
}

void ML_Log::UnInit()
{
	spdlog::drop_all();
	spdlog::shutdown();
}