#include "StdAfx.h"
#include "SystemLogManager.h"
#include "ServerStartErrorException.h"
#include "Dir.h"
#include "TextTools.h"
#include "DateUtility.h"

#define	CLASS_NAME			"SystemLogManager"
#define	MAX_OFFLINE_LOG		4096

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

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

///////////////////////////////////////////////////////////////////////////////////////////////////
//	操作
///////////////////////////////////////////////////////////////////////////////////////////////////
/*!
	開始
*/
void CSystemLogManager::Start(IServerToolPtr 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(CString callerName, CString statusInfo)
{
	SCOPE_LOCK();

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

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

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


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

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

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

	//	オフラインログを吐き出し
	while(!m_offlineLog.IsEmpty())
		WriteSystemLogToFile(m_offlineLog.RemoveHead());
}

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

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

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

