#include "StdAfx.h"
#include "CommandRecvPipe.h"
#include "SyncObject.h"
#include "CommandPacket.h"

#define	SEND_TIME_OUT_MS	(5 * 1000)

//	ステータス
enum CP_STATUS
{
	CP_STATUS_START				= 0,
	CP_STATUS_SENDING_WELECOME	= 1,
	CP_STATUS_RECEIVING_COMMAND = 3,
	CP_STATUS_SENDING_RESPONSE	= 4,
	CP_STATUS_CLOSE				= -1,
};


CCommandRecvPipe::CCommandRecvPipe(void)
{
	m_status = CP_STATUS_START;
	SetTimeOut(SEND_TIME_OUT_MS);
}

CCommandRecvPipe::~CCommandRecvPipe(void)
{
}

//////////////////////////////////////////////////////////////////////////////////////////
//	操作
//////////////////////////////////////////////////////////////////////////////////////////
/*!
	初期化
*/
int CCommandRecvPipe::Init(CPipeServer *reciver, CPipeCommandExecuteBase *executer, HANDLE pipe, ULONG_PTR CompletionKey)
{
	//	コピー
	m_reciver = reciver;
	m_executer = executer;

	//	パイプを初期化
	if(COverlapedPipe::Init(pipe, CompletionKey))
		return(-1);

	//	ウェルカムメッセージ生成
	if(BuildWelcomeMessage(m_sendData))
		return(-1);

	//	ウェルカムメッセージ送信開始
	m_status = CP_STATUS_SENDING_WELECOME;
	if(StartWaitSend())
	{
		Close();
		return(-1);
	}

	return(0);
}

/*!
	終了
*/
void CCommandRecvPipe::Close()
{
	COverlapedPipe::Close();

	SAFE_CLOSE_HANDLE(m_hPipe);
	m_status = CP_STATUS_CLOSE;
}


/*!
	処理
*/
int CCommandRecvPipe::PipeTask()
{
	//	完了処理
	if(EndOverlap())
	{
		Close();
		return(-1);
	}

	//	各処理に
	switch(m_status)
	{
		//	ウェルカムメッセージ送信完了
		case CP_STATUS_SENDING_WELECOME:
		{
			//	コマンドメッセージを待つ
			m_status = CP_STATUS_RECEIVING_COMMAND;
			if(StartWaitRecv())
			{
				Close();
				return(-1);
			}
			break;
		}

		//	コマンドメッセージ受信完了
		case CP_STATUS_RECEIVING_COMMAND:
		{
			//	呼び出し
			if(OnRecvCommand(m_recvData, m_sendData))
			{
				Close();
				return(-1);
			}

			//	レスポンスを送信開始
			m_status = CP_STATUS_SENDING_RESPONSE;
			if(StartWaitSend())
			{
				Close();
				return(-1);
			}
			break;
		}

		//	コマンドレスポンス送信完了
		case CP_STATUS_SENDING_RESPONSE:
		{
			//	次のコマンドメッセージを待つ
			m_status = CP_STATUS_RECEIVING_COMMAND;
			if(StartWaitRecv())
			{
				Close();
				return(-1);
			}
			break;
		}

		default:
			return(-1);
	}

	return(0);
}


//////////////////////////////////////////////////////////////////////////////////////////
//	内部関数
//////////////////////////////////////////////////////////////////////////////////////////
/*!
	切断チェック
*/
int CCommandRecvPipe::CheckDisconnect()
{
	//	切断中
	if(m_hPipe == NULL)
		return(1);

	//	時間制限のある処理を実行中か？
	if(	m_status == CP_STATUS_SENDING_WELECOME || 
		m_status == CP_STATUS_SENDING_RESPONSE)
	{
		if(IsTimeout())
		{
			Close();
			return(1);
		}
	}

	return(0);
}

/*!
	ウェルカムメッセージ生成
*/
int CCommandRecvPipe::BuildWelcomeMessage(CBuffer &sendData)
{
	//	サーバ情報設定
	CCommandPacket	welcome;
	welcome.SetCommand(_T("Welcome"));
	welcome.SetCommandOption(_T("ServerName"), _T(SERVER_NAME));
	welcome.SetCommandOption(_T("ServerVersion"), _T(SERVER_VER));
	welcome.SetCommandOption(_T("SupportedInterface"), _T(SERVER_SUPPORT_CONTROL_INTERFACE));

	welcome.ToBuffer(sendData);
	return(0);
}


/*!
	コマンド呼び出し
*/
int CCommandRecvPipe::OnRecvCommand(CBuffer &recvData, CBuffer &sendData)
{
	return m_executer->OnRecvCommand(m_recvData, m_sendData);
}

