#include "StdAfx.h"
#include "ServerStatusManager.h"
#include "Dir.h"
#include "TextTools.h"
#include "DateUtility.h"

#define	MAX_SYSTEM_LOG		200
#define	MAX_NOTIFY			200
#define	MAX_STATUS			200
#define	CLASS_NAME			"StatusManager"


CServerStatusManager::CServerStatusManager(void)
{
	m_serverStatus = m_statusRoot.GetAccess("ServerStatus");
}

CServerStatusManager::~CServerStatusManager(void)
{
}


///////////////////////////////////////////////////////////////////////////////////////////////////
//	操作
///////////////////////////////////////////////////////////////////////////////////////////////////
/*!
	開始
*/
void CServerStatusManager::Start(CIServerToolWrap serverTool)
{
	ASSERT(!m_init);
	m_init = TRUE;

	//	システムログ
	m_systemLog.Start(serverTool.GetIServerTool());
}

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

	//	停止
	m_systemLog.Stop();

	m_init = FALSE;
}

/*!
	ログを出力
*/
void CServerStatusManager::WriteSystemLog(CString callerName, int logType, CString logString)
{
	//	ワークスペースをロック
	WORKSPACE_LOCK(m_serverStatus);

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

	//	最新アイテム取得
	CServerSystemLog systemLog = m_serverStatus.GetSystemLog().GetNewItem();
	systemLog.SetCaller(callerName);
	systemLog.SetLogType(logType);
	systemLog.SetLogString(logString);
	systemLog.SetTime(CDateUtility::GetTimeString(CTime::GetCurrentTime()));

	//	アイテム数確認
	if(m_serverStatus.GetSystemLog().GetItemCount() > MAX_SYSTEM_LOG)
		m_serverStatus.GetSystemLog().DeleteItem(0);

	TRACE("<%s> %s\n", callerName, logString);

	//	必要ならログファイルへ
	if(logType <= SYSTEM_LOG_INFO_LOG)
		m_systemLog.WriteSystemLog(callerName, logString);

	//	必要なら通知
	if(logType <= SYSTEM_LOG_WARNING)
	{
		if(logType <= SYSTEM_LOG_ERROR)
			NotifyServerMessage("SystemLogErrorNotify", "エラーが発生しました: " + logString, SYSTEM_MESSAGE_ERROR);
		else
			NotifyServerMessage("SystemLogWarningNotify", "警告が発生しました: " + logString, SYSTEM_MESSAGE_WARNING, 60 * 60);	//	1時間で自動消去
	}
};


/*!
	サーバステータスの変更
*/
void CServerStatusManager::SetServerStatus(CString statusName, CString status, CString statusInfo, CString statusType)
{
	//	ワークスペースをロック
	WORKSPACE_LOCK(m_serverStatus);

	//	ステータス数確認
	if(m_serverStatus.GetServerStatusCount() >= MAX_STATUS)
		return;	//	これ以上追加不能

	//	エントリ取得
	CServerStatusEntry entry = m_serverStatus.GetServerStatusEntry(statusName);

	//	エントリ設定
	entry.SetStatus(status);
	if(!statusInfo.IsEmpty())
		entry.SetStatusInfo(statusInfo);
	if(!statusType.IsEmpty())
		entry.SetStatusType(statusType);
}

/*!
	サーバメッセージを通知
*/
void CServerStatusManager::NotifyServerMessage(CString messageID, CString message, int messageType, int autoOffTimeSec)
{
	//	ワークスペースをロック
	WORKSPACE_LOCK(m_serverStatus);

	//	ステータス数確認
	if(m_serverStatus.GetServerNotifyCount() >= MAX_NOTIFY)
		return;	//	これ以上追加不能

	//	エントリ取得
	CServerNotifyEntry entry = m_serverStatus.GetServerNotifyEntry(messageID);

	//	エントリ設定
	entry.SetMessageID(messageID);
	entry.SetMessage(message);
	entry.SetMessageType(messageType);
	entry.SetAutoOffTimeSec(autoOffTimeSec);
	entry.SetTime(CDateUtility::GetTimeString(CTime::GetCurrentTime()));
}


///////////////////////////////////////////////////////////////////////////////////////////////////
//	取得
///////////////////////////////////////////////////////////////////////////////////////////////////
/*!
	ステータス取得
*/
void CServerStatusManager::DuplicateStatus(CWorkspace &status)
{
	status.Duplicate(m_statusRoot);
}
