#pragma once
#include "iresponse.h"
#include "ConnectionToolWrap.h"
#include "BinaryData.h"


/*!
	レスポンスファクトリ ベース
*/
class CResponseFactoryBase
{
public:
	//!	コンストラクタ
	CResponseFactoryBase(void)
	{
		m_interface.SetResponseFactoryBase(this);
	}

	//!	デストラクタ
	virtual ~CResponseFactoryBase(void)
	{
	}

	//!	インタフェース取得
	IResponseFactoryPtr GetIResponseFactory()
	{
		return &m_interface;
	}

protected:
	//////////////////////////////////////////////////////////////////////////////////////////////
	//	初期化
	//////////////////////////////////////////////////////////////////////////////////////////////
	//!	初期化
	virtual void Start(CIServerToolWrap serverTool) {};

	//!	停止
	virtual void Stop() {};

	//!	削除
	virtual void Delete() {};

	//////////////////////////////////////////////////////////////////////////////////////////////
	//	取得
	//////////////////////////////////////////////////////////////////////////////////////////////
	//!	自分のアイテムか？
	virtual int IsYourRequest(CContext context) = 0;

	//!	レスポンス取得
	virtual IResponsePtr GetResponse() = 0;

protected:
	//////////////////////////////////////////////////////////////////////////////////////////////
	//	レスポンスインタフェース
	//////////////////////////////////////////////////////////////////////////////////////////////
	//!	レスポンスインタフェース
	class CResponseFactoryInterface : public IResponseFactory
	{
	public:
		CResponseFactoryInterface()
		{
			m_responseFactory = NULL;
		}

		//!	実装をセット
		void SetResponseFactoryBase(CResponseFactoryBase *responseFactory)
		{
			m_responseFactory = responseFactory;
		}

		//!	初期化
		virtual void Start(IServerToolPtr serverTool)
		{
			m_responseFactory->Start(serverTool);
		}

		//!	停止
		virtual void Stop()
		{
			m_responseFactory->Stop();
		}

		//!	削除
		virtual void Delete()
		{
			m_responseFactory->Delete();
		}

		//!	自分のアイテムか？
		virtual int IsYourRequest(IWorkspaceAccessPtr context)
		{
			return m_responseFactory->IsYourRequest(CWorkspaceAccess(context));
		}

		//!	レスポンス取得
		virtual IResponsePtr GetResponse()
		{
			return m_responseFactory->GetResponse();
		}

	protected:
		//////////////////////////////////////////////////////////////////////////////////////////////
		//	メンバ変数
		//////////////////////////////////////////////////////////////////////////////////////////////
		//!	実装
		CResponseFactoryBase	*m_responseFactory;
	};

protected:
	//////////////////////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	//////////////////////////////////////////////////////////////////////////////////////////////
	//!	インタフェース
	CResponseFactoryInterface	m_interface;
};


/*!
	レスポンス ベース
*/
class CResponseBase
{
public:
	//!	コンストラクタ
	CResponseBase(void)
	{
		m_interface.SetFilterBase(this);
	};

	//!	デストラクタ
	virtual ~CResponseBase(void)
	{
	};

	//!	インタフェース取得
	IResponsePtr GetIResponse()
	{
		return &m_interface;
	}

protected:
	//////////////////////////////////////////////////////////////////////////////////////////////
	//	初期化
	//////////////////////////////////////////////////////////////////////////////////////////////
	//!	初期化(例外発生厳禁！)
	virtual void Start(CIConnectionToolWrap responseContext) {};

	//!	停止(例外発生厳禁！)
	virtual void Stop(CIConnectionToolWrap responseContext)  {};

	//!	削除
	virtual void Delete() {};

	//!	フィルタ名取得
	virtual LPCTSTR GetResponseName() = 0;

	//////////////////////////////////////////////////////////////////////////////////////////////
	//	レスポンス生成
	//////////////////////////////////////////////////////////////////////////////////////////////
	//!	1:リクエストヘッダ設定
	virtual void SetRequest(CIConnectionToolWrap responseContext) {};

	//!	2:リクエストボディ設定(繰り返し)
	virtual void SetRequestBody(CIConnectionToolWrap responseContext, CBinaryData &body) {};

	//!	3:リクエスト完了
	virtual void EndRequest(CIConnectionToolWrap responseContext) {};


	//!	4:レスポンス生成
	virtual void BuildResponse(CIConnectionToolWrap responseContext) {};


	//!	5:レスポンスヘッダ取得
	virtual void GetResponse(CIConnectionToolWrap responseContext) {};

	//!	6:レスポンスボディ取得
	virtual int GetResponseBody(CIConnectionToolWrap responseContext, CBinaryData &body, int blockSize) { return 0; };

	//!	7:レスポンス完了
	virtual void EndResponse(CIConnectionToolWrap responseContext) {};

protected:
	//////////////////////////////////////////////////////////////////////////////////////////////
	//	レスポンスインタフェース
	//////////////////////////////////////////////////////////////////////////////////////////////
	//!	レスポンスインタフェース
	class CResponseInterface : public IResponse
	{
	public:
		//!	コンストラクタ
		CResponseInterface()
		{
			m_responseBase = NULL;
		}

		//!	実装をセット
		void SetFilterBase(CResponseBase *responseBase)
		{
			m_responseBase = responseBase;
		}

		//////////////////////////////////////////////////////////////////////////////////////////////
		//	初期化
		//////////////////////////////////////////////////////////////////////////////////////////////
		//!	初期化(例外発生厳禁！)
		virtual void Start(IConnectionToolPtr responseContext)
		{
			m_responseBase->Start(responseContext);
		}

		//!	停止(例外発生厳禁！)
		virtual void Stop(IConnectionToolPtr responseContext)
		{
			m_responseBase->Stop(responseContext);
		}

		//!	レスポンス名取得(必ずstatic領域に宣言しなければならない)
		virtual LPCTSTR GetResponseName()
		{
			return m_responseBase->GetResponseName();
		}

		//!	削除
		virtual void Delete()
		{
			m_responseBase->Delete();
		}

		//////////////////////////////////////////////////////////////////////////////////////////////
		//	レスポンス生成
		//////////////////////////////////////////////////////////////////////////////////////////////
		//!	1:リクエストヘッダ設定
		virtual void SetRequest(IConnectionToolPtr responseContext)
		{
			m_responseBase->SetRequest(responseContext);
		}

		//!	2:リクエストボディ設定(繰り返し)
		virtual void SetRequestBody(IConnectionToolPtr responseContext, IBinaryDataPtr body)
		{
			m_responseBase->SetRequestBody(responseContext, CBinaryData(body));
		}

		//!	3:リクエスト完了
		virtual void EndRequest(IConnectionToolPtr responseContext)
		{
			m_responseBase->EndRequest(responseContext);
		}

		//!	4:レスポンス生成
		virtual void BuildResponse(IConnectionToolPtr responseContext)
		{
			m_responseBase->BuildResponse(responseContext);
		}

		//!	5:レスポンスヘッダ取得
		virtual void GetResponse(IConnectionToolPtr responseContext)
		{
			m_responseBase->GetResponse(responseContext);
		}

		//!	6:レスポンスボディ取得
		virtual int GetResponseBody(IConnectionToolPtr responseContext, IBinaryDataPtr body, int blockSize)
		{
			return m_responseBase->GetResponseBody(responseContext, CBinaryData(body), blockSize);
		}

		//!	7:レスポンス完了
		virtual void EndResponse(IConnectionToolPtr responseContext)
		{
			m_responseBase->EndResponse(responseContext);
		}

	protected:
		//////////////////////////////////////////////////////////////////////////////////////////////
		//	メンバ変数
		//////////////////////////////////////////////////////////////////////////////////////////////
		//!	実装
		CResponseBase	*m_responseBase;
	};

protected:
	//////////////////////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	//////////////////////////////////////////////////////////////////////////////////////////////
	//!	インタフェース
	CResponseInterface	m_interface;
};
