#pragma once
#include "AuthenticateManager.h"
#include "Workspace.h"
#include "Request.h"
#include "Alias.h"

enum AUTH_PARSE_STATUS
{
	//	認証情報なし
	AUTH_PARSE_STATUS_NONE		= 0,

	//	認証情報期限切れ
	AUTH_PARSE_STATUS_EXPIRE	= 10,

	//	認証失敗
	AUTH_PARSE_STATUS_FAILE		= 20,

	//	認証成功
	AUTH_PARSE_STATUS_OK		= 30,

	//	異常な認証
	AUTH_PARSE_STATUS_ERROR		= -1,
};

/*!
	ダイジェスト認証クラス
*/
class CDigestAuthenticate
{
public:
	/////////////////////////////////////////////////////////////////////////////////////////
	//	チェック
	/////////////////////////////////////////////////////////////////////////////////////////
	//!	認証方式を解析
	static AUTH_PARSE_STATUS ParseAuthMethod(CAuthenticateManager *manager, CAlias &alias, CRequest &request);

	/////////////////////////////////////////////////////////////////////////////////////////
	//	生成
	/////////////////////////////////////////////////////////////////////////////////////////
	//!	認証ライン取得
	static CString GetAuthOptionLine(int isDigest, CAuthenticateManager *manager, CAlias &alias, int stale);

	//!	認証ラインを取得
	static CString GetBasicAuthOptionLine(CAlias &alias);

	//!	認証ラインを取得
	static CString GetDigestAuthOptionLine(CAuthenticateManager *manager, CAlias &alias, int stale);

protected:
	/////////////////////////////////////////////////////////////////////////////////////////
	//	Basic認証
	/////////////////////////////////////////////////////////////////////////////////////////
	//!	基本認証の分析
	static int ParseBasicAuth(CString authLine, CRequest &request);

	//!	基本認証の認証チェック
	static int CheckBasicAuthUser(CAuthenticateManager *manager, CAlias &alias, CRequest &request);


	/////////////////////////////////////////////////////////////////////////////////////////
	//	Digest認証
	/////////////////////////////////////////////////////////////////////////////////////////
	//!	ダイジェスト認証を分析
	static int ParseDigestAuth(CString optionLine, CRequest &request);

	//!	ダイジェスト認証の詳細チェック
	static int CheckDigestAuthRequest(CAuthenticateManager *manager, CAlias &alias, CRequest &request);

	//!	レスポンスチェック
	static int CheckDigestAuthResponse(CAuthenticateManager *manager, CAlias &alias, CRequest &request, CString tag = _T(""));

	//!	期限チェック
	static int CheckDigestAuthExpire(CAuthenticateManager *manager, CAlias &alias, CRequest &request);

	//!	認証チェック
	static int CheckDigestAuthUser(CAuthenticateManager *manager, CAlias &alias, CRequest &request);


	/////////////////////////////////////////////////////////////////////////////////////////
	//	補助関数
	/////////////////////////////////////////////////////////////////////////////////////////
	//!	ユーザ名・パスワードを確認
	static int GetUserPasswd(CAuthenticateManager *manager, CAlias &alias, CString userName, CString &passwd);

	//!	URIの一致を確認
	static int CheckURIMatch(CString serverURI, CString clientURI);

	//!	realm取得
	static CString GetRealm(CString realmSrc);
};
