#include "StdAfx.h"
#include "Server.h"
#include "DirTools.h"
#include "ServerException.h"

#define	CLASS_NAME	_U8("Server")

CServer::CServer(void)
{
}

CServer::~CServer(void)
{
	StopServer();
}


//!	デバッグ
void CServer::Dump()
{
	if(m_serverRunning)
	{
		/*
		//	コンテキストダンプ実行
		CWorkspace	context;
		DWORD tick = GetTickCount();
		m_connectionManager.GetIConetextManager()->DuplicateContext(context);
		TRACE_U8("DuplicateContext : %d\n", GetTickCount() - tick);

		tick = GetTickCount();
		context.SaveToXMLFile(CPathTools::GetAppPath() + "Context.xml");
		TRACE_U8("SaveToXMLFile : %d\n", GetTickCount() - tick);


		//	ステータスダンプ実行
		CWorkspace	status;
		tick = GetTickCount();
		m_statusManager.DuplicateStatus(status);
		TRACE_U8("DuplicateContext : %d\n", GetTickCount() - tick);

		tick = GetTickCount();
		status.SaveToXMLFile(CPathTools::GetAppPath() + _U8("Status.xml"));
		TRACE_U8("SaveToXMLFile : %d\n", GetTickCount() - tick);
	*/
	}
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//	IServerControl
/////////////////////////////////////////////////////////////////////////////////////////////////
/*!
	サーバの開始
*/
void CServer::StartServer()
{
	//	実行中？
	if(m_serverRunning)
		return;
	m_serverRunning = TRUE;

	//	初期化エラー
	try
	{
		//	状態更新
		m_statusManager.WriteSystemLog(CLASS_NAME, SYSTEM_LOG_INFO_LOG,	_U16("サーバの実行を開始します"));

		/*
			管理機能初期化
		*/
		//	インタフェースマネージャ初期化
		m_interfaceManager.Start(GetIServerTool());

		//	設定マネージャ初期化
		m_settingManager.Start(GetIServerTool());

		//	ステータスマネージャ初期化
		m_statusManager.Start(GetIServerTool());
		m_statusManager.NotifyServerMessage(_U8("ServerInit"), _U16("サーバを起動中です"), SYSTEM_MESSAGE_WARNING);

#if 0
		/*
			補助機能初期化
		*/
		m_supportManagers.Start(GetIServerTool());

		/*
			モジュール初期化
		*/
		//	フィルタマネージャ初期化
		m_filterManager.Start(GetIServerTool());

		//	レスポンスマネージャ起動
		m_responseManager.Start(GetIServerTool());

#endif

		/*
			通信機能初期化
		*/
		//	接続マネージャ開始
		m_connectionManager.Start(GetIServerTool());

		//	リスナ初期化
		m_listenerManager.Start(GetIServerTool(), m_connectionManager.GetIClientConnectionQueue());

		//	状態更新
		m_statusManager.WriteSystemLog(CLASS_NAME, SYSTEM_LOG_INFO_LOG,	_U16("サーバの初期化を完了しました"));
		m_statusManager.SetServerStatusInt(_U8("ServerRunning"), 1, _U16("サーバ実行状態"));
		m_statusManager.NotifyServerMessage(_U8("ServerInit"), _U8(""), SYSTEM_MESSAGE_OFF);
	}
	catch(CServerErrorExceptionBase &err)	//	エラー例外をまとめて受ける
	{
		//	エラーをセット
		m_statusManager.WriteSystemLog(err.GetCaller(), SYSTEM_LOG_FATAL_ERROR, err.GetErrorInfo());

		//	停止
		StopServer();
	}
}

/*!
	サーバの停止
*/
void CServer::StopServer()
{
	//	実行中？
	if(!m_serverRunning)
		return;
	m_serverRunning = FALSE;

	//	状態更新
	m_statusManager.WriteSystemLog(CLASS_NAME, SYSTEM_LOG_INFO_LOG, _U16("サーバの停止処理を開始します"));

	/*
		通信機能停止
	*/
	//	通信停止
	m_listenerManager.ShutdownListen();

	//	接続マネージャ停止
	m_connectionManager.Stop();

	//	リスナ停止
	m_listenerManager.Stop();

#if 0

	/*
		モジュール停止
	*/
	//	レスポンスマネージャ停止
	m_responseManager.Stop();

	//	フィルタマネージャ停止
	m_filterManager.Stop();

	/*
		補助機能停止
	*/
	m_supportManagers.Stop();
#endif

	/*
		管理機能停止
	*/

	//	設定マネージャ停止
	m_settingManager.Stop();

	//	ステータスマネージャ停止
	m_statusManager.Stop();

	//	インタフェースマネージャ停止
	m_interfaceManager.Stop();

	//	状態更新
	m_statusManager.WriteSystemLog(CLASS_NAME, SYSTEM_LOG_INFO_LOG, _U16("サーバの実行を停止しました"));
	m_statusManager.SetServerStatusInt(_U8("ServerRunning"), 0);
}


/*!
	コンテキスト取得
*/
void CServer::DuplicateCurrentContext(CWorkspace &contextRoot)
{
	if(m_serverRunning)
	{
		//	コンテキスト取得
//		m_connectionManager.GetIConetextManager()->DuplicateContext(contextRoot);
	}
}

/*!
	サーバステータス取得
*/
void CServer::DuplicateServerStatus(CWorkspace &statusRoot)
{
	if(m_serverRunning)
	{
		//	サーバステータス取得
		m_statusManager.DuplicateStatus(statusRoot);
	}
}

/////////////////////////////////////////////////////////////////////////////////////////////////
//	IServerTool
/////////////////////////////////////////////////////////////////////////////////////////////////
/*!
	ワークスペースへのアクセスを取得
*/
int CServer::GetServerWorkspaceAccess(IWorkspaceAccessRefPtr accessRef, LPCU8STR type, LPCU8STR section)
{
	CUTF8String	csType(type);

	//	空っぽに
	accessRef->SetWorkspaceAccess(NULL, _U8(""));

	//	タイプ別
	if(csType == MANAGER_SETTING)
	{
		m_settingManager.GetManagerSetting(section).FillIWorkspaceAccessRef(accessRef);
		return(0);
	}
	else if(csType == FILTER_SETTING)
	{
		m_settingManager.GetFilterSetting(section).FillIWorkspaceAccessRef(accessRef);
		return(0);
	}
	else if(csType == RESPONSE_SETTING)
	{
		m_settingManager.GetFilterSetting(section).FillIWorkspaceAccessRef(accessRef);
		return(0);
	}
	else if(csType == SERVER_STATUS)
	{
		m_statusManager.GetStatus().FillIWorkspaceAccessRef(accessRef);
		return(0);
	}
	else
		return(-1);
}


/*!
	サーバステータスの変更
*/
void CServer::WriteSystemLog(LPCU8STR callerName, int logType, LPCU8STR logString)
{
	m_statusManager.WriteSystemLog(callerName, logType, logString);
}


/*!
	サーバステータスの変更
*/
void CServer::SetServerStatus(LPCU8STR statusName, LPCU8STR status, LPCU8STR statusInfo, LPCU8STR statusType)
{
	m_statusManager.SetServerStatus(statusName, status, statusInfo, statusType);
}

/*!
	サーバメッセージを通知
*/
void CServer::NotifyServerMessage(LPCU8STR messageID, LPCU8STR message, int messageType, int autoOffTimeSec)
{
	m_statusManager.NotifyServerMessage(messageID, message, messageType, autoOffTimeSec);
}

/*!
	インタフェース登録
*/
int CServer::RegisterManagerInterface(LPCU8STR interfaceName, IManagerInterfacePtr ifRegister, IManagerInterfacePtr *oldInterface)
{
	return(m_interfaceManager.RegisterInterface(interfaceName, ifRegister, oldInterface));
}

/*!
	インターフェース登録解除
*/
int CServer::UnRegisterManagerInterface(LPCU8STR interfaceName, IManagerInterfacePtr ifUnRegister, IManagerInterfacePtr oldInterface)
{
	return(m_interfaceManager.UnRegisterInterface(interfaceName, ifUnRegister, oldInterface));
}

/*!
	インタフェース取得
*/
void *CServer::GetManagerInterface(LPCU8STR interfaceName, int ifVersion)
{
	//	取得を試みる
	return m_interfaceManager.GetInterface(interfaceName, ifVersion);
}
