#pragma once
#include "MySocket.h"
#include "Config.h"
#include "threadskeleton.h"
#include "response.h"
#include "request.h"
#include "alias.h"
#include "bandwidthmgr.h"

class CServer;

class CConnectionException
{
public:
	CConnectionException(CString info,int retry=0) {m_info = info;m_retry = retry;}

	CString	m_info;
	int		m_retry;
};

class CServerFatalException
{
public:
	CServerFatalException(CString info)
	{
		m_info = info;
	}

	CString	m_info;
};

//	レスポンスの中断など、割り込みを確認する
class CConnection;
class CConnectionInterrupt
{
public:
	CConnectionInterrupt(CConnection *connection);
	CConnectionInterrupt(CConnectionInterrupt &other);
	
	int IsInterrupt();
	operator int();
	CString GetInterruptInfo();

private:
	CConnection		*m_connection;
	CString			m_interruptInfo;
};

class CConnection : public CThreadSkeleton, public CTimeOut
{
	friend class CConnectionInterrupt;

public:
	CConnection(CServer *server,CMySocket *socket);
	virtual ~CConnection(void);
	CConfigAccess GetDate(int detail=0);			//!<	日付取得
	virtual void Break();

protected:
	//	オーバーロード
	void ThreadMain();
	virtual void OnTimeOut();

	int SSLTask();
	CConfigAccess NewContext();
	void DeleteContext(CConfigAccess context);
	int OneRequest(CConfigAccess context);
	CString RecvHeader();
	void SendFatalError(CString info);
	CString MakeHeaderString(CConfigAccess responseInfo);

	void WriteLog(CConfigAccess &context);
	void UpdateTransSize(CConfigAccess &context);

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//	レスポンス作成
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//!	アクセスチェック
	void CheckAccess(CConfigAccess &context,CRequest &request,CAlias &alias,CBandWidthReference &bandRef);

	//!	ユーザーチェック
	void CheckUser(CConfigAccess &context,CRequest &request,CAlias &alias);

	//!	ホストチェック
	int CheckKickHost(CConfigAccess &context,CRequest &request,CAlias &alias);

	//!	移動の確認
	void CheckMove(CConfigAccess &context,CRequest &request,CAlias &alias);

	//!	WebDAV処理
	void WebDAV(CConfigAccess &context,CRequest &request,CAlias &alias);

	//!	Index確認
	void CheckIndex(CConfigAccess &context,CRequest &request,CAlias &alias);

	//!	CGI
	void CGI(CConfigAccess &context,CRequest &request,CAlias &alias);

	//!	SSI
	void SSI(CConfigAccess &context,CRequest &request,CAlias &alias);

	void SendResponse(CConfigAccess &context,CRequest &request,CAlias &alias,CBandWidthReference &bandRef,CResponse *response);
	void RecvData(CConfigAccess &context,CRequest &request,CAlias &alias,CBandWidthReference &bandRef,CResponse *response);
	void SendData(CConfigAccess &context,CRequest &request,CAlias &alias,CBandWidthReference &bandRef,CResponse *response,__int64 length);

	int CheckUser(CString userName,CString passwd,CAlias alias);
	void Delay(int tick);
	

	int						m_maxKeepAliveTime;	//!<	KeepAlive時間
	int						m_keepAlive;		//!<	KeepAlive許可
	CConfig					m_date;				//!<	日付処理用環境領域

	__int64					m_sendSize;
	__int64					m_recvSize;
	__int64					m_recvDataSize;;

	CServer					*m_server;
	CMySocket				*m_socket;			//!<	ソケット
	CConnectionInterrupt	m_interrupt;
};

