#include "StdAfx.h"
#include "SystemLogManager.h"
#include "ServerException.h"
#include "DirTools.h"
#include "DateTools.h"

#define	CLASS_NAME			_U8("SystemLogManager")
#define	MAX_OFFLINE_LOG		4096

CSystemLogManager::CSystemLogManager(void)
{
	//	デフォルトログ名
	m_logName = CPathTools::GetAppPath() + _U8("Logs\\SystemLog.txt");
}

CSystemLogManager::~CSystemLogManager(void)
{
	Stop();
	FlashOfflineLog();
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//	操作
///////////////////////////////////////////////////////////////////////////////////////////////////
/*!
	開始
*/
void CSystemLogManager::Start(CIServerToolWrap serverTool)
{
	//	初期化済み？
	if(m_init)
		return;
	m_init = TRUE;

	//	設定取得
	m_setting = serverTool.GetManagerSetting(m_setting.GetSettingName());
	m_logName = m_setting.GetSystemLogFilePath();

	//	開始前のログを出力
	FlashOfflineLog();
}

/*!
	停止
*/
void CSystemLogManager::Stop()
{
	//	初期化チェック
	if(!m_init)
		return;

	//	終了
	m_init = FALSE;
}

/*!
	システムログへ出力
*/
void CSystemLogManager::WriteSystemLog(CUTF8String callerName, CUTF8String statusInfo)
{
	CRITICAL_SECTION_SCOPE();

	//	安全のため
	statusInfo.Replace(_U8("\r"), _U8("_"));
	statusInfo.Replace(_U8("\n"), _U8("_"));

	if(m_init)
	{
		if(!m_offlineLog.IsEmpty())
			FlashOfflineLog();

		WriteSystemLogToFile(CUTF8String::GetFormat(_U8("[%s] <%s> %s\n"), CDateTools::GetTimeString(CTime_t::GetCurrentTime()), callerName, statusInfo));
	}
	else
	{
		//	オフラインログへ追加
		AddOfflineLog(CUTF8String::GetFormat(_U8("[%s] <%s> %s\n"), CDateTools::GetTimeString(CTime_t::GetCurrentTime()), callerName, statusInfo));
	}
}


///////////////////////////////////////////////////////////////////////////////////////////////////
//	ツール
///////////////////////////////////////////////////////////////////////////////////////////////////
/*!
	オフラインログへ追加
*/
void CSystemLogManager::AddOfflineLog(CUTF8String log)
{
	CRITICAL_SECTION_SCOPE();

	if(m_offlineLog.GetCount() < MAX_OFFLINE_LOG)
		m_offlineLog.AddTail(log);
}

/*!
	オフラインログをすべて出力
*/
void CSystemLogManager::FlashOfflineLog()
{
	CRITICAL_SECTION_SCOPE();

	//	オフラインログを吐き出し
	for(int i=0;i<m_offlineLog.GetCount();i++)
		WriteSystemLogToFile(m_offlineLog[i]);
	m_offlineLog.RemoveAll();
}

/*!
	システムログへ出力
*/
void CSystemLogManager::WriteSystemLogToFile(CUTF8String log)
{
	CRITICAL_SECTION_SCOPE();

	//	全てのディレクトリを作っておく
	static CUTF8String	oldLogName;
	if(oldLogName != m_logName)
	{
		CFileDirTools::MakeAllDirectory(CPathTools::PathToDir(m_logName));
		oldLogName = m_logName; 
	}

	//	ファイルを書きこみ
	FILE	*logFile;
	if(!_wfopen_s(&logFile, _cnvU16(m_logName), _U16("at+")))
	{
		fwprintf(logFile, _U16("%s"), log);
		fclose(logFile);
	}
}

