/*!
	CSettingManager

	設定マネージャ
	%ServerRoot% のみ、自動的に置き換えが実行される
*/
#include "StdAfx.h"
#include "SettingManager.h"
#include "ServerException.h"
#include "DirTools.h"

//!	このクラスの名前
#define	CLASS_NAME	_U8("SettingManager")

///////////////////////////////////////////////////////////////////////////////////////////////////
//	コンストラクタ
///////////////////////////////////////////////////////////////////////////////////////////////////
CSettingManager::CSettingManager(void) :
	m_settingRoot(_U8("04WebServer2"))
{
	m_serverSetting = m_settingRoot.GetAccess(_U8("Setting"));
}

CSettingManager::~CSettingManager(void)
{
}


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

	//	設定のロード
	if(m_settingRoot.LoadFromXMLFile(SETTING_FILE))
		throw CServerStartErrorException(CLASS_NAME, _U16("設定ファイル [") + SETTING_FILE + _U16("] の読み込みに失敗しました。"));

	//	置き換え
	OverwriteSetting(m_serverSetting);

	//	標準の自動置き換え
	EnableAutoSwapDefault(TRUE);

	//	リードオンリーに
	m_settingRoot.SetReadOnly(TRUE);
}

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

	//	標準の自動置き換え停止
	EnableAutoSwapDefault(FALSE);

}

///////////////////////////////////////////////////////////////////////////////////////////////////
//	設定上書き
///////////////////////////////////////////////////////////////////////////////////////////////////
/*!
	設定を上書きする(再帰)
*/
void CSettingManager::OverwriteSetting(CWorkspaceAccess overwrite)
{
	OverwriteOneSetting(overwrite);

	//	全サブノードを取得
	CUTF8StringArray	nodes;
	overwrite.GetAllSubNode(nodes);

	//	下位を書き換え
	for(int i=0;i<nodes.GetCount();i++)
		OverwriteSetting(overwrite.GetAccess(nodes[i]));
}

/*!
	設定を上書きする
*/
void CSettingManager::OverwriteOneSetting(CWorkspaceAccess overwrite)
{
	//	全キーを取得
	CUTF8StringArray	keys;
	overwrite.GetAllKey(keys);

	//	すべて上書き
	for(int i=0;i<keys.GetCount();i++)
	{
		CUTF8String	data = overwrite.GetKeyStr(keys[i], _U8(""));

		//	サーバルート
		data.Replace(_U8("%ServerRoot%"), CPathTools::GetAppPath());

		//	書き戻す
		overwrite.SetKeyStr(keys[i], data);
	}
}


/*!
	デフォルト値の自動書き換えを有効に

	指定されるデフォルト値に置き換えが含まれていた時の対策
*/
void CSettingManager::EnableAutoSwapDefault(int enable)
{
	if(enable)
	{
		//	サーバルート
		m_settingSwap.AddSwap(_U8("%ServerRoot%"), CPathTools::GetAppPath());

		//	書き換えを設定(デフォルト値が指定されている場合のみ)
		m_settingRoot.SetAutoSwapDefault(&m_settingSwap);
	}
	else
	{
		//	無効に
		m_settingRoot.SetAutoSwapDefault(NULL);
	}
}

/*!
	通常の取得
*/
CUTF8String CSettingWorkspaceSwap::GetKeyDataSwap(IWorkspace *workspace, const LPCU8STR orgKey, CUTF8String orgData)
{
	CRITICAL_SECTION_SCOPE();

	//	置き換え文字を検索
	if(orgData.Find(_U8("%")) != -1)
	{
		//	置き換え実行
		for(int i=0;i<m_keyData.GetCount();i++)
			orgData.Replace(m_keyData[i].GetKey(), m_keyData[i].GetData());
	}

	return(orgData);
}

/*!
	置き換えを追加
*/
void CSettingWorkspaceSwap::AddSwap(CUTF8String key, CUTF8String swap)
{
	CRITICAL_SECTION_SCOPE();

	m_keyData.Add(key, swap);
}
