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

#define	CLASS_NAME	"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("DuplicateContext : %d\n", GetTickCount() - tick);

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


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

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

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

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

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

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

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


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

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

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


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

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


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

		//	停止
		StopServer();
	}
}

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

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

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

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

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


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

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

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

	/*
		管理機能停止
	*/

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

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

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

	//	状態更新
	WriteSystemLog(CLASS_NAME, SYSTEM_LOG_INFO_LOG, "サーバの実行を停止しました");
	m_statusManager.SetServerStatusInt("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, LPCSTR type, LPCSTR section)
{
	CString	csType(type);

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

	//	タイプ別
	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(LPCSTR callerName, int logType, LPCSTR logString)
{
	m_statusManager.WriteSystemLog(callerName, logType, logString);
}


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

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

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

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

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