#include "StdAfx.h"
#include "ResponseManager.h"
#include "IResponse.h"
#include "FileResponse.h"
#include "DirectoryIndexResponse.h"

/*!
	レスポンスレベル
*/
enum RESPONSE_LEVEL
{
	RESPONSE_LEVEL_CGI			= 400000,

	RESPONSE_LEVEL_DIRECTORY	= 500000,

	RESPONSE_LEVEL_FILE			= 1000000,
};

CResponseManager::CResponseManager(void)
{
}

CResponseManager::~CResponseManager(void)
{
}


//////////////////////////////////////////////////////////////////////////////////////////////
//	初期化・終了
//////////////////////////////////////////////////////////////////////////////////////////////
/*!
	開始
*/
void CResponseManager::Start(CIServerToolWrap serverTool)
{
	//	初期化済み？
	if(m_init)
		return;
	m_init = TRUE;

	m_serverTool = serverTool;

	//	標準レスポンス追加
	AddBasicResponses();

	//	初期化
	for(int i=0;i<m_responseFactorys.GetSize();i++)
		m_responseFactorys[i].Start(m_serverTool.GetIServerTool());

	//	インタフェース初期化
	m_managerInterface.Init((IResponseManagerPtr)this, RESPONSE_MANAGER_INTERFACE_VER);

	//	インターフェース登録
	m_serverTool.RegisterManagerInterface(RESPONSE_MANAGER_INTERFACE_NAME, m_managerInterface.GetIManagerInterface());
}

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

	//	停止
	for(int i=0;i<m_responseFactorys.GetSize();i++)
		m_responseFactorys[i].Stop();

	m_responseFactorys.RemoveAll();

	//	インターフェース登録解除
	m_serverTool.UnRegisterManagerInterface(RESPONSE_MANAGER_INTERFACE_NAME, m_managerInterface.GetIManagerInterface());
}


/*!
	レスポンス生成
*/
IResponsePtr CResponseManager::GetResponse(CContext context)
{
	SCOPE_LOCK();

	//	検索
	for(int i=0;i<m_responseFactorys.GetSize();i++)
	{
		if(m_responseFactorys[i].IsYourRequest(context.GetIWorkspaceAccess()))
			return m_responseFactorys[i].GetResponse();
	}

	return NULL;	//	NULLを返す
}


//////////////////////////////////////////////////////////////////////////////////////////////
//	補助
//////////////////////////////////////////////////////////////////////////////////////////////
/*!
	基本レスポンス追加
*/
void CResponseManager::AddBasicResponses()
{
	//	ディレクトリレスポンス
	AddResponsesFactory((new CDirectoryIndexResponseFactory())->GetIResponseFactory(),	RESPONSE_LEVEL_DIRECTORY);

	//	ファイルレスポンス
	AddResponsesFactory((new CFileResponseFactory())->GetIResponseFactory(),			RESPONSE_LEVEL_FILE);
}

/*!
	レスポンス追加
*/
void CResponseManager::AddResponsesFactory(IResponseFactoryPtr factory, int responseLevel)
{
	//	挿入場所を検索
	for(int i=0;i<m_responseFactorys.GetSize();i++)
	{
		if(m_responseFactorys[i].GetResponseLevel() > responseLevel)
		{
			//	挿入
			m_responseFactorys.InsertAt(i, CResponseFactoryArrayItem(CIResponseFactoryWrapper::CreateWrapper(factory), responseLevel));
			return;
		}
	}

	//	最後
	m_responseFactorys.Add(CResponseFactoryArrayItem(CIResponseFactoryWrapper::CreateWrapper(factory), responseLevel));
}

