/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JFUUrlConnection
*   ソースファイル名：JFUUrlConnection.java
*   作成者          ：富士通
*   日付            ：2011年06月23日
*＜機能概要＞
*   フロント用HTTP又はSSLリクエストの送信部品
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2011/07/30   FJ）西川    新規作成
*  v28.00.00    2016/10/12   FJ) 横山   【ANK-3032-00-00】AxM再構築対応
*  v38.00.00    2018/09/19   FJ) 西川   【ANK-3508-00-00】パズル認証対応
*  v53.00       2021/04/16   FJ) 張本   【ANK-4009-00-00】CX戦略WG方針対応
*
**********************************************************************/
package eo.web.webview.common;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import eo.common.constant.JFUStrConst;

/**
 * フロント用HTTP又はSSLリクエスト送信の部品です。
 * <br>
 * @author 富士通
 */
public class JFUUrlConnection
{

	/** SSL */
	protected static final String SSL_PROTOCOL = "SSL";
	/** SSL 接頭語 */
	protected static final String SSL_URL_PROTOCOL = "https";
	/** リクエストメソッド POST */
	protected static final String REQUEST_METHOD_POST = "POST";
	/** リクエストメソッド GET */
	protected static final String REQUEST_METHOD_GET = "GET";
	/** イコール */
	protected static final String EQUAL_SIGN = "=";
	/** 空文字 */
	protected static final String EMPTY = "";
	/** オブジェクトの初期容量 */
	protected static final int DEFAULT_INITIAL_CAPACITY = 16;

	/** メールサポート連携URL値取得キー */
	protected static final String KEY_MAILSUPPORT_URL = "FU_C_API_IF_MAILSUPPORT_URL";

	/** PITS(汎用個人情報取込API)APIのURL値取得キー */
	protected static final String KEY_PITS_COM_PERSON_URL = "FU_C_API_IF_PITS_COM_PERSON_URL";

	/** Capy稼動監視API URL取得キー */
	protected static final String KEY_CAPY_STATUS_URL = "API_CAPY_STATUS_URL";

	/** Capy回答照会API URL取得キー */
	protected static final String KEY_CAPY_VERIFY_URL = "API_CAPY_VERIFY_URL";

	/** ソーシャルIDアクセストークン取得API（Facebook） URL取得キー */
	protected static final String KEY_FACEBOOK_GET_TOKEN_URL = "API_FACEBOOK_GET_TOKEN_URL";

	/** ソーシャルIDユーザ情報取得API（Facebook） URL取得キー */
	protected static final String KEY_FACEBOOK_GET_USER_URL = "API_FACEBOOK_GET_USER_URL";

	/** ソーシャルIDアクセストークン取得API（Google） URL取得キー */
	protected static final String KEY_GOOGLE_GET_TOKEN_URL = "API_GOOGLE_GET_TOKEN_URL";

	/** ソーシャルIDユーザ情報取得API（Google） URL取得キー */
	protected static final String KEY_GOOGLE_GET_USER_URL = "API_GOOGLE_GET_USER_URL";

	/** ソーシャルIDアクセストークン取得API（Yahoo） URL取得キー */
	protected static final String KEY_YAHOO_GET_TOKEN_URL = "API_YAHOO_GET_TOKEN_URL";

	/** ソーシャルIDユーザ情報取得API（Yahoo） URL取得キー */
	protected static final String KEY_YAHOO_GET_USER_URL = "API_YAHOO_GET_USER_URL";

	/**
	 * 接続情報を生成する。
	 *
	 * <br>
	 * @param urlKey 接続先URLキー
	 * @param timeOut タイムアウト時間
	 * @return 生成した接続情報
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws IOException
	 */
	protected static HttpURLConnection createConnection(String urlKey, int timeOut) throws NoSuchAlgorithmException,
			KeyManagementException, IOException
	{
		HttpURLConnection conn = null;
		String requestMethod = REQUEST_METHOD_POST;

		// URL生成
		URL url = null;
		if (KEY_MAILSUPPORT_URL.equals(urlKey))
		{
			// メールサポート連携URL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_MAILSUPPORT_URL));
		}
		else if (KEY_PITS_COM_PERSON_URL.equals(urlKey))
		{
			// PITS(汎用個人情報取込API)APIのURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_PITS_COM_PERSON_URL));
		}
		else if (JFUStrConst.IDA_NINSHO_URL_KEY.equals(urlKey))
		{
			// iDA認証送信処理（authenticateApi）のURL
			url = new URL(JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NINSHO_URL_KEY));
		}
		else if (JFUStrConst.IDA_NINSHO_CONF_URL_KEY.equals(urlKey))
		{
			// iDA認証確認送信処理（authConfirmApi）のURL
			url = new URL(JCCWebCommon.getApplicationConst(JFUStrConst.IDA_NINSHO_CONF_URL_KEY));
		}
		else if (KEY_CAPY_STATUS_URL.equals(urlKey))
		{
			// Capy稼動監視APIのURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_CAPY_STATUS_URL));
			requestMethod = REQUEST_METHOD_GET;
		}
		else if (KEY_CAPY_VERIFY_URL.equals(urlKey))
		{
			// Capy回答照会APIのURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_CAPY_VERIFY_URL));
		}
		else if (KEY_FACEBOOK_GET_TOKEN_URL.equals(urlKey))
		{
			// ソーシャルIDアクセストークン取得APIのURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_FACEBOOK_GET_TOKEN_URL));
		}
		else if (KEY_FACEBOOK_GET_USER_URL.equals(urlKey))
		{
			// ソーシャルIDユーザ情報取得API のURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_FACEBOOK_GET_USER_URL));
		}
		else if (KEY_GOOGLE_GET_TOKEN_URL.equals(urlKey))
		{
			// ソーシャルIDアクセストークン取得APIのURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_GOOGLE_GET_TOKEN_URL));
		}
		else if (KEY_GOOGLE_GET_USER_URL.equals(urlKey))
		{
			// ソーシャルIDユーザ情報取得API のURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_GOOGLE_GET_USER_URL));
		}
		else if (KEY_YAHOO_GET_TOKEN_URL.equals(urlKey))
		{
			// ソーシャルIDアクセストークン取得APIのURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_YAHOO_GET_TOKEN_URL));
		}
		else if (KEY_YAHOO_GET_USER_URL.equals(urlKey))
		{
			// ソーシャルIDユーザ情報取得API のURL
			url = new URL(JCCWebCommon.getApplicationConst(KEY_YAHOO_GET_USER_URL));
		}

		if (null == url)
		{
			return conn;
		}

		if (SSL_URL_PROTOCOL.equals(url.getProtocol()))
		{
			// https接続の場合の設定
			KeyManager[] km = null;

			TrustManager[] tm = { new X509TrustManager()
			{

				/**
				 * クライアントSSL認証の信頼性チェック
				 *
				 * <br>
				 * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], java.lang.String)
				 * @param age0 ピアの証明書チェーン
				 * @param age1 クライアント証明書に基づいた認証タイプ
				 * @throws CertificateException
				 */
				public void checkClientTrusted(X509Certificate[] age0, String age1) throws CertificateException
				{
				}

				/**
				 * サーバーSSL認証の信頼性チェック
				 *
				 * <br>
				 * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String)
				 * @param age0 ピアの証明書チェーン
				 * @param age1 使用される鍵交換アルゴリズム
				 * @throws CertificateException
				 */
				public void checkServerTrusted(X509Certificate[] age0, String age1) throws CertificateException
				{
				}

				/**
				 * 証明書発行局の証明書配列の取得
				 *
				 * <br>
				 * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
				 * @return 受け入れ可能なCA発行証明書配列
				 */
				public X509Certificate[] getAcceptedIssuers()
				{
					return null;
				}
			} };
			SSLContext sslcontext = SSLContext.getInstance(SSL_PROTOCOL);
			sslcontext.init(km, tm, new SecureRandom());
			HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier()
			{

				/**
				 * 証明書の認証チェック
				 *
				 * <br>
				 * @see javax.net.ssl.HostnameVerifier#verify(java.lang.String, javax.net.ssl.SSLSession)
				 * @param aHostname 認証先
				 * @param aSession 証明書情報
				 * @return true：認証OK、false:認証NG
				 */
				public boolean verify(String aHostname, SSLSession aSession)
				{
					return true;
				}
			});
			HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
			conn = (HttpsURLConnection)url.openConnection();
		}
		else
		{
			// http接続の場合の設定
			conn = (HttpURLConnection)url.openConnection();
		}

		// POST送信を可能にする。
		conn.setRequestMethod(requestMethod);
		conn.setDoOutput(true);
		// タイムアウトを設定
		conn.setConnectTimeout(timeOut);
		// キャッシュ使用
		conn.setUseCaches(false);

		return conn;
	}

	/**
	 * HTTP/SSLリクエスト(POST)を送信する。
	 *
	 * <br>
	 * @param conn 接続情報
	 * @param key キー
	 * @param value 値
	 * @param encoding 文字コード
	 * @return 接続結果情報
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws IOException
	 */
	protected static HttpURLConnection connection(HttpURLConnection conn, String key, String value, String encoding)
			throws NoSuchAlgorithmException, KeyManagementException, IOException
	{
		DataOutputStream dos = null;
		try
		{
			dos = new DataOutputStream(conn.getOutputStream());
			byte[] paramByte = (key + EQUAL_SIGN + URLEncoder.encode(value, encoding)).getBytes();
			dos.write(paramByte, 0, paramByte.length);
		}
		finally
		{
			if (null != dos)
			{
				dos.close();
			}
		}
		// 接続実行
		conn.connect();

		return conn;
	}

	/**
	 * HTTP/SSLリクエスト(POST)を送信する。
	 *
	 * <br>
	 * @param conn 接続情報
	 * @param param POSTパラメータ
	 * @return 接続結果情報
	 * @throws IOException
	 */
	protected static HttpURLConnection connection(HttpURLConnection conn, String param, String encoding) throws IOException
	{

		// POSTパラメータを設定
		OutputStream os = conn.getOutputStream();
		PrintStream ps = new PrintStream(os);
		// データをPOSTする
		ps.print(param);
		ps.close();

		// 接続実行
		conn.connect();

		return conn;
	}

	/**
	 * タイムアウト値を返却する。（デフォルト：5秒）
	 * 
	 * @param timeOutKey アプリケーションプロパティに定義したタイムアウト値取得キー
	 * @return タイムアウト値
	 */
	protected static int getTimeOut(String timeOutKey)
	{
		int timeOut = 5000;
		String timeOutStr = JCCWebCommon.getApplicationConst(timeOutKey);
		if (!JFUWebCommon.isNull(timeOutStr) && timeOutStr.matches("^[0-9]+$"))
		{
			timeOut = Integer.parseInt(timeOutStr);
		}
		return timeOut;
	}

}
