/*********************************************************************
 * All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *   システム名      ：eo顧客基幹システム
 *   モジュール名    ：JFUSocialFacebookInterface
 *   ソースファイル名：JFUSocialFacebookInterface.java
 *   作成者          ：富士通
 *   日付            ：2021年04月08日
 *＜機能概要＞
 *   ソーシャルID認証（FaceBook）の外部APIを呼び出すIF部品です。
 *＜修正履歴＞
 *   バージョン  修正日       修正者      修正内容
 *   v53.00      2021/04/08   FJ）張本    【ANK-4009-00-00】CX戦略WG方針対応
 *
 **********************************************************************/
package eo.web.webview.common;

import static com.fujitsu.futurity.web.x31.X31SWebLog.DEBUG_LOG;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Map.Entry;

import org.json.JSONObject;

import com.fujitsu.futurity.web.x31.X31SWebLog;

import eo.common.constant.JFUStrConst;

/**
 * ソーシャルID認証（FaceBook）の外部APIを呼び出すIF部品です。
 *
 * <br>
 * @author 富士通
 * @see JFUUrlConnection フロント用HTTP又はSSLリクエストの送信部品
 */
public class JFUSocialFacebookInterface extends JFUUrlConnection
{

	/** ソーシャルID認証　クライアントID */
	public static final String CLIENT_ID = "client_id";
	/** ソーシャルID認証　クライアントシークレット */
	public static final String CLIENT_SECRET = "client_secret";
	/** ソーシャルID認証　リダイレクトURI */
	public static final String REDIRECT_URI = "redirect_uri";
	/** ソーシャルID認証　認可コード */
	public static final String CODE = "code";

	/** ソーシャルIDアクセストークン取得　アクセストークン */
	public static final String ACCESS_TOKEN = "access_token";
	/** ソーシャルIDアクセストークン取得　トークンタイプ */
	public static final String TOKEN_TYPE = "token_type";
	/** ソーシャルIDアクセストークン取得　アクセストークン有効期限 */
	public static final String EXIRES_IN = "exires_in";

	/** ソーシャルIDユーザ情報取得 フィールド */
	public static final String FIELDS = "fields";
	/** ソーシャルIDユーザ情報取得 ユーザー識別ID */
	public static final String ID = "id";
	/** ソーシャルIDユーザ情報取得 姓 */
	public static final String LAST_NAME = "last_name";
	/** ソーシャルIDユーザ情報取得 名 */
	public static final String FIRST_NAME = "first_name";
	/** ソーシャルIDユーザ情報取得 生年月日 */
	public static final String USER_BIRTHDAY = "user_birthday";
	/** ソーシャルIDユーザ情報取得 性別 */
	public static final String USER_GENDER = "user_gender";
	/** ソーシャルIDユーザ情報取得 メールアドレス */
	public static final String EMAIL = "email";

	/** ソーシャルID認証 クライアントID値 取得キー */
	public static final String KEY_API_FACEBOOK_CLIENT_ID = "API_FACEBOOK_CLIENT_ID";
	/** ソーシャルID認証 クライアントシークレット値 取得キー */
	public static final String KEY_API_FACEBOOK_CLIENT_SECRET = "API_FACEBOOK_CLIENT_SECRET";
	/** ソーシャルID認証 リダイレクトURI値 取得キー */
	public static final String KEY_API_FACEBOOK_REDIRECT_URI = "API_FACEBOOK_REDIRECT_URI";
	/** ソーシャルID認証 レスポンスタイプ値 取得キー */
	public static final String KEY_API_FACEBOOK_RESPONSE_TYPE = "API_FACEBOOK_RESPONSE_TYPE";
	/** ソーシャルID認証 スコープ値 取得キー */
	public static final String KEY_API_FACEBOOK_SCOPE = "API_FACEBOOK_SCOPE";

	/** ソーシャルIDアクセストークン取得（FaceBook）API タイムアウト値取得キー */
	private static final String STATUS_TIMEOUT = "API_FACEBOOK_STATUS_TIMEOUT";
	/** ソーシャルIDアクセストークン取得（FaceBook）API 文字コード取得キー */
	private static final String STATUS_CHARCODE = "API_FACEBOOK_STATUS_CHARCODE";

	/** ソーシャルIDユーザ情報取得（FaceBook）フィールド */
	private static final String KEY_API_FACEBOOK_FIELDS = "API_FACEBOOK_FIELDS";

	/** 性別：male */
	public static final String GENDER_MALE = "male";
	/** 性別：female */
	public static final String GENDER_FEMALE = "female";

	/**
	 * ソーシャルIDアクセストークン取得APIを実施します。
	 *
	 * <br>
	 * @param code 認可コード
	 * @return 処理結果
	 */
	public static HashMap<String, Object> getSocialIdTokenReqRslt(String code)
	{
		HashMap<String, String> inMap = new HashMap<String, String>();

		String clientId = JCCWebCommon.getApplicationConst(KEY_API_FACEBOOK_CLIENT_ID);
		String clientSecret = JCCWebCommon.getApplicationConst(KEY_API_FACEBOOK_CLIENT_SECRET);
		String redirectUri = JCCWebCommon.getApplicationConst(KEY_API_FACEBOOK_REDIRECT_URI);

		inMap.put(CLIENT_ID, clientId);
		inMap.put(CLIENT_SECRET, clientSecret);
		inMap.put(REDIRECT_URI, redirectUri);
		inMap.put(CODE, code);

		X31SWebLog.DEBUG_LOG.debug("【開始】ソーシャルIDアクセストークン取得（FaceBook）API");
		X31SWebLog.DEBUG_LOG.debug("FUIFE181(Req) :" + inMap);
		HashMap<String, Object> result = execute(inMap, KEY_FACEBOOK_GET_TOKEN_URL);
		X31SWebLog.DEBUG_LOG.debug("FUIFE181(Res) :" + result);
		X31SWebLog.DEBUG_LOG.debug("【終了】ソーシャルIDアクセストークン取得（FaceBook）API");
		return result;
	}

	/**
	 * ソーシャルIDユーザ情報取得APIを実施します。
	 *
	 * <br>
	 * @param accessToken アクセストークン
	 * @return 処理結果
	 */
	public static HashMap<String, Object> getSocialIdUserInfoReqRslt(String accessToken)
	{
		HashMap<String, String> inMap = new HashMap<String, String>();
		inMap.put(FIELDS, JCCWebCommon.getApplicationConst(KEY_API_FACEBOOK_FIELDS));
		inMap.put(ACCESS_TOKEN, accessToken);

		X31SWebLog.DEBUG_LOG.debug("【開始】ソーシャルIDユーザ情報取得（FaceBook）API");
		X31SWebLog.DEBUG_LOG.debug("FUIFE182(Req) :" + inMap);
		HashMap<String, Object> result = execute(inMap, KEY_FACEBOOK_GET_USER_URL);
		X31SWebLog.DEBUG_LOG.debug("FUIFE182(Res) :" + result);
		X31SWebLog.DEBUG_LOG.debug("【終了】ソーシャルIDユーザ情報取得（FaceBook）API");
		return result;
	}

	/**
	 * ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）APIを呼び出します。
	 *
	 * <br>
	 * @param inMap 送信情報
	 * @param urlKey 外部APIのURLキー
	 * @return 処理結果
	 */
	private static HashMap<String, Object> execute(HashMap<String, String> inMap, String urlKey)
	{
		HashMap<String, Object> result = null;

		// 正常時
		result = connect(inMap, urlKey);
		//		if (result.length() > 3 && VERIFY_RESULT_SUCCESS.equals(result.substring(0, 4)))
		//		{
		//			result = VERIFY_RESULT_SUCCESS;
		//		}
		return result;
	}

	/**
	 * ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）APIの呼び出し
	 * 
	 * @param inMap リクエスト情報
	 * @param urlKey URLキー
	 * @return レスポンス情報
	 */
	@SuppressWarnings("unchecked")
	private static HashMap<String, Object> connect(HashMap<String, String> inMap, String urlKey)
	{
		X31SWebLog.DEBUG_LOG.debug("【開始】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）API 接続処理(connect)");

		HttpURLConnection conn = null;
		HashMap<String, Object> resMap = new HashMap<String, Object>();
		int statusCode = 999;
		try
		{
			// リクエストタイムアウト値
			int timeOut = Integer.parseInt(JCCWebCommon.getApplicationConst(STATUS_TIMEOUT));
			// HTTPリクエストエンコード
			String encoding = JCCWebCommon.getApplicationConst(STATUS_CHARCODE);
			conn = createConnection(urlKey, timeOut);

			X31SWebLog.DEBUG_LOG.debug("【処理中】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）：URL：" + conn.getURL());
			X31SWebLog.DEBUG_LOG.debug("【処理中】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）：文字コード：" + encoding);
			X31SWebLog.DEBUG_LOG.debug("【処理中】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）：タイムアウト：" + timeOut);

			Set<Entry<String, String>> resSet = inMap.entrySet();
			StringBuffer sb = new StringBuffer();

			int i = 0;
			for (Iterator<Entry<String, String>> iterator = resSet.iterator(); iterator.hasNext();)
			{
				sb.append(i == 0 ? JFUStrConst.EMPTY : JFUStrConst.HALF_AMPERSAND);
				Entry<String, String> entry = iterator.next();
				X31SWebLog.DEBUG_LOG.debug("【処理中】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）：" + entry.getKey() + JFUStrConst.HALF_COLON + entry.getValue());
				sb.append(entry.getKey()).append(EQUAL_SIGN).append(entry.getValue());
				i++;
			}
			String param = sb.toString();
			conn = connection(conn, param, encoding);

			statusCode = conn.getResponseCode();

			X31SWebLog.DEBUG_LOG.debug("【処理中】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）：HTTPステータス：" + statusCode);

			if (statusCode == 200)
			{

				BufferedInputStream bis = null;
				ByteArrayOutputStream bos = null;
				byte[] outputByte = null;
				try
				{
					bis = new BufferedInputStream(conn.getInputStream());
					// レスポンスを読込み
					bos = new ByteArrayOutputStream();
					int intByte = 0;
					while (true)
					{
						intByte = bis.read();
						if (-1 == intByte)
						{
							break;
						}
						bos.write(intByte);
					}
					outputByte = bos.toByteArray();
				}
				catch (Exception e)
				{
					X31SWebLog.DEBUG_LOG.debug("【処理中】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）：例外発生：" + e);
				}
				finally
				{
					if (null != bos)
					{
						bos.close();
					}
					if (null != bis)
					{
						bis.close();
					}
				}

				if (outputByte != null)
				{
					String res = new String(outputByte, encoding);

					JSONObject rceiveObject = new JSONObject(res);
					DEBUG_LOG.info("DEBUG：ソーシャルID取得処理 out項目=" + rceiveObject.toString());

					for (Iterator<String> iterator = rceiveObject.keys(); iterator.hasNext();)
					{
						String key = iterator.next();
						resMap.put(key, rceiveObject.get(key));
					}
				}
			}
		}
		catch (Exception e)
		{
			X31SWebLog.DEBUG_LOG.debug("【処理中】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）：例外発生：" + e);
		}
		finally
		{
			if (null != conn)
			{
				conn.disconnect();
			}
		}
		X31SWebLog.DEBUG_LOG.debug("【処理中】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）：外部APIからのレスポンス：" + resMap.toString());
		X31SWebLog.DEBUG_LOG.debug("【終了】ソーシャルIDアクセストークン取得／ユーザ情報取得（FaceBook）API 接続処理(connect)");
		return resMap;
	}
}