#pragma once

#include "Workspace.h"
#include "threadskeleton.h"
#include "MySocket.h"
#include "logwriter.h"
#include "mimetypemgr.h"
#include "bandwidthmgr.h"
#include "fastlistener.h"


/*!
	class CServerException

	サーバーエラー
*/
class CServerException
{
public:
	CServerException(CString info,int retry=0) {m_info = info;m_retry = retry;}

	CString	m_info;
	int		m_retry;
};

/*!
	class CSettingSwap

	サーバ設定の置き換え
*/
class CSettingSwap : public IWorkspaceAutoSwap
{
public:
	CSettingSwap(CWorkspaceAccess serverInfo) {m_serverInfo = serverInfo;};
	CString SwapString(CString key,CString data);
	void Delete() { delete this; };

	CWorkspaceAccess	m_serverInfo;	
};


/*!
	class CServer

	サーバ処理を行います
*/
class CServer : public CThreadSkeleton, public CTimeOut
{
public:
	CServer(void);
	virtual ~CServer(void);

	int GetNewID();
	CMimeTypeMgr GetCMimeTypeMgr() {SCOPE_LOCK(); return m_mimeTypes;};
	CBandWidthMgr *GetCBandWidthMgr() {return &m_bandWidthMgr;};
	void AddTrans(__int64 send,__int64 recv) {m_bandWidthMgr.AddTrans(send,recv);};
	void SetServerStatus(CString status);
	int GetConnectCount();

private:
	void InitServerInfo(void);				//!<	サーバ情報の設定
	int StartListen(void);					//!<	待ち受け開始
	void ThreadMain();						//!<	スレッド本体
	void SendBusy(CMySocket *socket);		//!<	503を送信
	void KillAllConnection();				//!<	全ての接続の停止

	virtual void OnTimeOut();				//!<	タイムアウトハンドラ

	int				m_maxConnect;			//!<	最大接続数
	CMySocket		*m_errorSocket;			//!<	エラー用ソケット
	CPtrArray		m_connections;			//!<	接続
	int				m_IDCounter;			//!<	IDカウンタ
	CMimeTypeMgr	m_mimeTypes;			//!<	MimeTypeのキャッシュ
	CBandWidthMgr	m_bandWidthMgr;			//!<	帯域制限
	CFastListener	m_listener;				//!<	マルチスレッドリスナ

public:
	CWorkspace			m_context;				//!<	コンテキストルート
	CWorkspace			m_settingRoot;			//!<	設定ルート
	CWorkspace			m_infoRoot;				//!<	サーバ情報ルート
	CWorkspaceAccess	m_setting;				//!<	設定
	CWorkspaceAccess	m_threadContext;		//!<	スレッド環境領域
	CWorkspaceAccess	m_threadContextLog;		//!<	スレッド環境領域のログ
	CWorkspaceAccess	m_serverInfo;			//!<	サーバ情報環境領域
	CTime			m_statusUpdate;			//!<	サーバステータスが変更された時刻

	CLogWriter		m_log;					//!<	ログライター
};

