/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JCCAxMNinsho
*   ソースファイル名：JCCAxMNinsho.java
*   作成者          ：富士通
*   日付            ：2011年08月01日
*＜機能概要＞
* AxM認証部品です。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v18.00.00   2015/08/11   FJ) 阪口   【ANK-2631-00-00】ワンストップ案件（ＳＴＥＰ１）※koptWebBからkoptWebAへコピー
*
**********************************************************************/

package eo.web.webview.commonOneStop;

import static com.fujitsu.futurity.web.x31.X31SWebLog.DEBUG_LOG;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import sirrus.connect.ConnectionDescriptor;
import sirrus.runtime.APIFactory;
import sirrus.runtime.AuthTypes;
import sirrus.runtime.CredentialConstants;
import sirrus.runtime.OptionConstants;
import sirrus.runtime.ResultConstants;
import sirrus.runtime.RuntimeAPI;
import sirrus.runtime.RuntimeAPIException;
import sirrus.runtime.UserConstants;

import com.fujitsu.futurity.web.x33.HttpDispatchContext;
import com.fujitsu.futurity.web.x33.X33CUtil;
import com.fujitsu.futurity.web.x33.X33WSessionController;

import eo.common.util.JCCFrameworkException;
import eo.web.webview.JCCWebBusinessLogic;

public class JCCAxMNinsho {
	
	// DISPATCHERサーバー名取得用のキー
	private static final String HOST_KEY = "AXM_DISPATCHER_HOST";
	
	// DISPATCHERサーバーポート番号取得用のキー
	private static final String PORT_KEY = "AXM_DISPATCHER_PORT";
	
	// テストモード取得用キー
	private static final String MODE_KEY = "AXM_TEST_MODE";
	
	// 返却値の状態設定用キー
	private static final String RESULT = "RESULT";
	
	// 返却値のSYSID設定用キー
	private static final String SYSID = "SYSID";
	
	// 返却値の会員種別設定用キー
	private static final String KIIN_SHUBT = "KIIN_SHUBT";
	
	// 返却値のニックネーム設定用キー
	private static final String NK_NM = "NK_NM";
	
	// 返却値の連絡先メールアドレス設定用キー
	private static final String RNRKSK_MR = "RNRKSK_MR";
	
	// 返却値の年齢フラグ設定用キー
	private static final String AGE_FLG = "AGE_FLG";
	
	// 返却値の標準コンテンツ同意フラグ設定用キー
	private static final String HYOJUN_KNTNT_DUI_FLG = "HYOJUN_KNTNT_DUI_FLG";
	
	// 返却値のISP利用停止フラグ設定用キー
	private static final String ISP_RYU_TIS_FLG = "ISP_RYU_TIS_FLG";
	
	// 返却値の会員状態設定用キー
	private static final String JYOUTAI = "JYOUTAI";
	
	// 返却値の会員種別特定フラグ設定用キー
	private static final String KIIN_TOKUTEI = "KIIN_TOKUTEI";
	
	// 返却値の性別設定用キー
	private static final String SIBT = "SIBT";
	
	// 返却値のテスト用IDフラグ設定用キー
	private static final String TST_ID_FLG = "TST_ID_FLG";
	
	// 返却値の登録フラグ設定用キー
	private static final String TURK_FLG = "TURK_FLG";
	
	// 返却値の管理者用フラグ(1)設定用キー
	private static final String ADMIN_FLG1 = "ADMIN_FLG1";
	
	// 返却値の管理者用フラグ(2)設定用キー
	private static final String ADMIN_FLG2 = "ADMIN_FLG2";
	
	// 返却値の管理者用フラグ(3)設定用キー
	private static final String ADMIN_FLG3 = "ADMIN_FLG3";
	
	// 返却値の更新年月日時分秒設定用キー
	private static final String U_DATE = "U_DATE";

// MOD 20120723 フロント）西川 案件番号「ANK-0024-02-00 【お客さまID非通知対応】はぴeの料金系」の対応 START
//	public static HashMap<String, String> getAxMCertifyResult(JCCWebBusinessLogic vlObj, String userId, String password)
	/**
	 * AxMシステムに対して、認証処理を要求し結果を返却します。
	 * <br>
	 * @param vlObj Viewロジックインスタンス
	 * @param userId ユーザーID
	 * @param password パスワード
	 * @param isCreateCookie 認証成功時のクッキー情報生成有無 true:有り、false:無し
	 * @return 結果
	 */
	public static HashMap<String, String> getAxMCertifyResult(JCCWebBusinessLogic vlObj, String userId, String password, boolean isCreateCookie)
// MOD 20120723 フロント）西川 案件番号「ANK-0024-02-00 【お客さまID非通知対応】はぴeの料金系」の対応 END
	{
		// パラメータチェック
		//Viewロジックインスタンスのチェック
		if (null == vlObj)
		{
			throw new JCCFrameworkException("引数のViewロジックインスタンスがnullです。");
		}
		// ユーザーIDのチェック
		if (null == userId || "".equals(userId))
		{
			HashMap<String, String> resultMap = new HashMap<String, String>();
			resultMap.put(RESULT, ResultConstants.UNKNOWN_USER);
			resultMap.put(SYSID, "");
			return resultMap;
		}
		// パスワードのチェック
		if (null == password || "".equals(password))
		{
			HashMap<String, String> resultMap = new HashMap<String, String>();
			resultMap.put(RESULT, ResultConstants.INVALID_PASSWORD);
			resultMap.put(SYSID, "");
			return resultMap;
		}
		
		// Dispatcherサーバー接続情報の取得
		// ホスト名取得
		String host = JCCWebCommon.getApplicationConst(HOST_KEY);
		if (null == host || "".equals(host))
		{
			throw new JCCFrameworkException("アプリケーションプロパティファイルにDispatcherサーバーのホスト名が設定されていません。");
		}
		
		// ポート番号の取得
		String portStr = JCCWebCommon.getApplicationConst(PORT_KEY);
		if (null == portStr || "".equals(portStr))
		{
			throw new JCCFrameworkException("アプリケーションプロパティファイルにDispatcherサーバーのポート番号が設定されていません。");
		}
		// 文字列→数値への変換
		int port = 0;
		try 
		{
			port = Integer.parseInt(portStr);
		} 
		catch (NumberFormatException e)
		{
			throw new JCCFrameworkException("アプリケーションプロパティファイルに設定されているDispatcherサーバーのポート番号が不正です。");
		}
		
		// テストモード設定の取得
		String testMode = JCCWebCommon.getApplicationConst(MODE_KEY);
		if (null != testMode && "ON".equals(testMode.toUpperCase()))
		{
			// テストモードの実施
			return getTestCertifyResult(userId);
		}
		
		// ConnectionDescriptorオブジェクトの生成
		ConnectionDescriptor disCon = new ConnectionDescriptor(host, port, ConnectionDescriptor.SSL_ANON);
		RuntimeAPI runtimeAPI = null;
		try {
			runtimeAPI = APIFactory.createFromServerDispatcher(disCon);
		} catch (RuntimeAPIException e) {
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(e);
			throw fe;
		}
		
		// 設定情報の格納
		HashMap userMap = new HashMap();
		// ユーザーIDの設定
		userMap.put(UserConstants.SC_USER_ID, userId);
		// パスワードの設定
		userMap.put(UserConstants.CREDENTIALS, password);
		// 認証方式の設定
		userMap.put(UserConstants.AUTHENTICATION_TYPE, AuthTypes.SC_BASIC);
		// 戻り値にSSOトークンを含めるオプション設定
		userMap.put(OptionConstants.TOKENS_OPTION, OptionConstants.ON);
		// 戻り値にユーザープロパティファイルを含めるオプション設定
		userMap.put(OptionConstants.PROPERTIES_OPTION, OptionConstants.ON);
		// 戻り値にユーザーグループ情報を含めりオプション設定
		userMap.put(OptionConstants.GROUPS_OPTION, OptionConstants.OFF);
		
		userMap.put(CredentialConstants.SC_TOKENS_ENABLED, OptionConstants.ON);
		
		// 認証
		HashMap returnMap = null;
		try
		{
			returnMap = (HashMap)runtimeAPI.authenticate(userMap);
		} catch (RuntimeAPIException e) {
			JCCFrameworkException fe = new JCCFrameworkException();
			fe.initCause(e);
			throw fe;
		}
		
		// 認証状態の取得
		String userStatus = (String)returnMap.get(ResultConstants.AUTHENTICATION_RESULT);
		DEBUG_LOG.info("userStatus　：　" + userStatus);
		
		// 結果返却処理
		HashMap<String, String> resultMap = new HashMap<String, String>();
		
		// resultMapの初期化
		resultMap.put(SYSID, "");
		resultMap.put(KIIN_SHUBT, "");
		resultMap.put(NK_NM, "");
		resultMap.put(RNRKSK_MR, "");
		resultMap.put(AGE_FLG, "");
		resultMap.put(HYOJUN_KNTNT_DUI_FLG, "");
		resultMap.put(ISP_RYU_TIS_FLG, "");
		resultMap.put(JYOUTAI, "");
		resultMap.put(KIIN_TOKUTEI, "");
		resultMap.put(SIBT, "");
		resultMap.put(TST_ID_FLG, "");
		resultMap.put(TURK_FLG, "");
		resultMap.put(ADMIN_FLG1, "");
		resultMap.put(ADMIN_FLG2, "");
		resultMap.put(ADMIN_FLG3, "");
		resultMap.put(U_DATE, "");
		
		if (userStatus.equals(ResultConstants.VALID_USER))
		{
			//認証成功時の処理
			String sessionId = vlObj.getSession().getViewParamId().getSessionID();
// MOD 20120723 フロント）西川 案件番号「ANK-0024-02-00 【お客さまID非通知対応】はぴeの料金系」の対応 START
//			createCookie(sessionId, returnMap);
			if (isCreateCookie)
			{
				// クッキー情報生成処理
				createCookie(sessionId, returnMap);
			}
// MOD 20120723 フロント）西川 案件番号「ANK-0024-02-00 【お客さまID非通知対応】はぴeの料金系」の対応 END

			resultMap.put(RESULT, userStatus);
			// RSAより公開されるプロパティ情報の設定
			Map<String, HashSet<?>> prop = (Map<String, HashSet<?>>)returnMap.get("CT_USER_PROPERTIES");
			
			if(prop != null)
			{
				
				if(prop.get("sysid") != null)
				{
					resultMap.put(SYSID, (String)((HashSet)prop.get("sysid")).iterator().next());
				}
				if(prop.get("kiin_shubt") != null)
				{
					resultMap.put(KIIN_SHUBT, (String)((HashSet)prop.get("kiin_shubt")).iterator().next());
				}
				if(prop.get("nk_nm") != null)
				{
					resultMap.put(NK_NM, (String)((HashSet)prop.get("nk_nm")).iterator().next());
				}
				if(prop.get("rnrksk_mr") != null)
				{
					resultMap.put(RNRKSK_MR, (String)((HashSet)prop.get("rnrksk_mr")).iterator().next());
				}
				if(prop.get("age_flg") != null)
				{
					resultMap.put(AGE_FLG, (String)((HashSet)prop.get("age_flg")).iterator().next());
				}
				if(prop.get("hyojun_kntnt_dui_flg") != null)
				{
					resultMap.put(HYOJUN_KNTNT_DUI_FLG, (String)((HashSet)prop.get("hyojun_kntnt_dui_flg")).iterator().next());
				}
				if(prop.get("isp_ryu_tis_flg") != null)
				{
					resultMap.put(ISP_RYU_TIS_FLG, (String)((HashSet)prop.get("isp_ryu_tis_flg")).iterator().next());
				}
				if(prop.get("jyoutai") != null)
				{
					resultMap.put(JYOUTAI, (String)((HashSet)prop.get("jyoutai")).iterator().next());
				}
				if(prop.get("kiin_tokutei") != null)
				{
					resultMap.put(KIIN_TOKUTEI, (String)((HashSet)prop.get("kiin_tokutei")).iterator().next());
				}
				if(prop.get("sibt") != null)
				{
					resultMap.put(SIBT, (String)((HashSet)prop.get("sibt")).iterator().next());
				}
				if(prop.get("tst_id_flg") != null)
				{
					resultMap.put(TST_ID_FLG, (String)((HashSet)prop.get("tst_id_flg")).iterator().next());
				}
				if(prop.get("turk_flg") != null)
				{
					resultMap.put(TURK_FLG, (String)((HashSet)prop.get("turk_flg")).iterator().next());
				}
				if(prop.get("admin_flg1") != null)
				{
					resultMap.put(ADMIN_FLG1, (String)((HashSet)prop.get("admin_flg1")).iterator().next());
				}
				if(prop.get("admin_flg2") != null)
				{
					resultMap.put(ADMIN_FLG2, (String)((HashSet)prop.get("admin_flg2")).iterator().next());
				}
				if(prop.get("admin_flg3") != null)
				{
					resultMap.put(ADMIN_FLG3, (String)((HashSet)prop.get("admin_flg3")).iterator().next());
				}
				if(prop.get("u_date") != null)
				{
					resultMap.put(U_DATE, (String)((HashSet)prop.get("u_date")).iterator().next());
				}
			}
		} else {
			resultMap.put(RESULT, userStatus);
		}
		
		// ログ
		setLog(resultMap);
		
		return resultMap;
	}

	/**
	 * Cookieの生成処理を行う
	 * <br>
	 * @param sessionId Viewロジックインスタンス
	 * @param returnMap 
	 */
	private static void createCookie(String sessionId, Map returnMap)
	{
		String token = (String) returnMap.get("SC_TOKEN");

// ST1-2012-0000466対応 20120903 fst)柳原 start
		// AXMより返却されるトークンをURLエンコードする。
		String axm_cokkie_urlencode = JCCWebCommon.getApplicationConst("AXM_COOKIE_URLENCODE");
		// アプリケーションプロパティに設定されていない場合はデフォルト値を設定
		if(axm_cokkie_urlencode == null)
		{
			axm_cokkie_urlencode = "UTF-8";
		}
		String token_encode = null;
		try
		{
			 token_encode = URLEncoder.encode(token, axm_cokkie_urlencode);
		}
		catch (UnsupportedEncodingException ue)
		{
			throw new JCCFrameworkException("不正なエンコードが指定されました。", ue);
		}
		// Cookieオブジェクトの生成
		//Cookie cookie = new Cookie("CTSESSION", token);
		Cookie cookie = new Cookie("CTSESSION", token_encode);

		// アプリケーションプロパティファイルよりCookieの属性値を取得する。
		String axm_cookie_domain = JCCWebCommon.getApplicationConst("AXM_COOKIE_DOMAIN");
		String axm_cookie_path = JCCWebCommon.getApplicationConst("AXM_COOKIE_PATH");
		String axm_cookie_age = JCCWebCommon.getApplicationConst("AXM_COOKIE_AGE");
		String axm_cookie_secure = JCCWebCommon.getApplicationConst("AXM_COOKIE_SECURE");
		
		// アプリケーションプロパティファイルの必須チェック
		if(axm_cookie_domain == null)
		{
			throw new JCCFrameworkException("APLConst.propertiesにAXM_COOKIE_DOMAINが設定されていません。");
		}
		if(axm_cookie_path == null)
		{
			throw new JCCFrameworkException("APLConst.propertiesにAXM_COOKIE_PATHが設定されていません。");
		}
		if(axm_cookie_age == null)
		{
			throw new JCCFrameworkException("APLConst.propertiesにAXM_COOKIE_AGEが設定されていません。");
		}
		if(axm_cookie_secure == null)
		{
			throw new JCCFrameworkException("APLConst.propertiesにAXM_COOKIE_SECUREが設定されていません。");
		}
		
		// Cookieへ属性を設定する。
		cookie.setDomain(axm_cookie_domain); // Cookieの有効ドメインを設定
		cookie.setPath(axm_cookie_path); // Cookieの有効パスを設定
		cookie.setMaxAge(Integer.parseInt(axm_cookie_age)); // Cookieの最長存続期間を設定
		cookie.setSecure(Boolean.parseBoolean(axm_cookie_secure)); // Cookieのsecure属性を設定
// ST1-2012-0000466対応 20120903 fst)柳原 end

		// HttpServletResponseオブジェクトの取得
		X33WSessionController sc = X33CUtil.getSession(sessionId);
		HttpServletResponse res = ((HttpDispatchContext)sc.getContext()).getServletResponse();
		// Cookieのセット
		res.addCookie(cookie);
	}

	/**
	 * テストモードでの認証処理
	 * <br>
	 * ユーザーIDにより返却値が変わる
	 * @param userId ユーザID
	 * @return テストモードでの認証結果
	 */
	private static HashMap<String, String> getTestCertifyResult(String userId)
	{
		
		int num = 0;
		HashMap<String, String> resultMap = new HashMap<String, String>();
		
		//ユーザーが存在しないときの設定
		resultMap.put(RESULT, ResultConstants.UNKNOWN_USER);
		resultMap.put(SYSID, "");
		
		// ユーザーIDが4ケタ以上あるかどうかの確認
		if (! (userId.length() >= 4))
		{
			return resultMap;
		}
		
		// 先頭がTどうかの確認
		if (! "T".equals(userId.substring(0, 1)))
		{
			return resultMap;
		}
		
		// 2桁目〜4桁目が整数値として扱えない場合
		String id2to4 = userId.substring(1, 4);
		try {
			num = Integer.parseInt(id2to4);
		} catch (NumberFormatException e) {
			return resultMap;
		}
		
		// 認証成功のユーザーID
		if ((num >= 0) && (num <= 9))
		{
			resultMap.put(RESULT, ResultConstants.VALID_USER);
			resultMap.put(SYSID, "9999");
		}
		
		// アカウント有効期限切れのユーザーID
		if ((num >= 10) && (num <= 19))
		{
			resultMap.put(RESULT, ResultConstants.EXPIRED_ACCOUNT);
			resultMap.put(SYSID, "");
		}
		
		// アカウントが無効のユーザーID
		if ((num >= 20) && (num <= 29))
		{
			resultMap.put(RESULT, ResultConstants.INACTIVE_ACCOUNT);
			resultMap.put(SYSID, "");
		}
		
		// アカウントがロックされているユーザーID
		if ((num >= 30) && (num <= 39))
		{
			resultMap.put(RESULT, ResultConstants.ADMIN_LOCKOUT);
			resultMap.put(SYSID, "");
		}
		
		// パスワードが無効のユーザーID
		if ((num >= 40) && (num <= 49))
		{
			resultMap.put(RESULT, ResultConstants.INVALID_PASSWORD);
			resultMap.put(SYSID, "");
		}
		
		// パスワードが有効期限切れのユーザーID
		if ((num >= 50) && (num <= 59))
		{
			resultMap.put(RESULT, ResultConstants.EXPIRED_PASSWORD);
			resultMap.put(SYSID, "");
		}
		
		// 管理者による強制的なパスワード有効期限切れのユーザーID
		if ((num >= 60) && (num <= 69))
		{
			resultMap.put(RESULT, ResultConstants.EXPIRED_PASSWORD_FORCED);
			resultMap.put(SYSID, "");
		}
		
		// アカウントが作成されてから一度もパスワードが設定されていないユーザーID
		if ((num >= 70) && (num <= 79))
		{
			resultMap.put(RESULT, ResultConstants.EXPIRED_PASSWORD_NEW_USER);
			resultMap.put(SYSID, "");
		}
		
		return resultMap;
	}
	
	/**
	 * resultMapのデバッグログ出力
	 * 
	 * <br>
	 * @param resultMap
	 */
	private static void setLog(HashMap<String, String> resultMap)
	{
		DEBUG_LOG.info("AxMAuth_sysid　：　" + resultMap.get(SYSID));
		DEBUG_LOG.info("AxMAuth_kiin_shubt　：　" + resultMap.get(KIIN_SHUBT));
		DEBUG_LOG.info("AxMAuth_nk_nm　：　" + resultMap.get(NK_NM));
		DEBUG_LOG.info("AxMAuth_rnrksk_mr　：　" + resultMap.get(RNRKSK_MR));
		DEBUG_LOG.info("AxMAuth_age_flg　：　" + resultMap.get(AGE_FLG));
		DEBUG_LOG.info("AxMAuth_hyojun_kntnt_dui_flg　：　" + resultMap.get(HYOJUN_KNTNT_DUI_FLG));
		DEBUG_LOG.info("AxMAuth_isp_ryu_tis_flg　：　" + resultMap.get(ISP_RYU_TIS_FLG));
		DEBUG_LOG.info("AxMAuth_jyoutai　：　" + resultMap.get(JYOUTAI));
		DEBUG_LOG.info("AxMAuth_kiin_tokutei　：　" + resultMap.get(KIIN_TOKUTEI));
		DEBUG_LOG.info("AxMAuth_sibt　：　" + resultMap.get(SIBT));
		DEBUG_LOG.info("AxMAuth_tst_id_flg　：　" + resultMap.get(TST_ID_FLG));
		DEBUG_LOG.info("AxMAuth_turk_flg　：　" + resultMap.get(TURK_FLG));
		DEBUG_LOG.info("AxMAuth_admin_flg1　：　" + resultMap.get(ADMIN_FLG1));
		DEBUG_LOG.info("AxMAuth_admin_flg2　：　" + resultMap.get(ADMIN_FLG2));
		DEBUG_LOG.info("AxMAuth_admin_flg3　：　" + resultMap.get(ADMIN_FLG3));
		DEBUG_LOG.info("AxMAuth_u_date　：　" + resultMap.get(U_DATE));
	}

}
