/*********************************************************************
 * All Rights reserved,Copyright (c) K-Opticom
 **********************************************************************
 *＜プログラム内容＞
 *   システム名      ：eo顧客基幹システム
 *   モジュール名    ：JFUMailSupportInterface
 *   ソースファイル名：JFUMailSupportInterface.java
 *   作成者          ：富士通
 *   日付            ：2011年06月23日
 *＜機能概要＞
 *   メールサポートシステムの外部APIを呼び出すIF部品です。
 *＜修正履歴＞
 *   バージョン  修正日       修正者      修正内容
 *   v1.00.00    2011/06/23   FJ）西川    新規作成
 *
 **********************************************************************/
package eo.web.webview.common;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import com.fujitsu.futurity.web.x31.X31SWebLog;

/**
 * メールサポートシステムの外部APIを呼び出すIF部品です。
 *
 * <br>
 * @author 富士通
 * @see JFUUrlConnection フロント用HTTP又はSSLリクエストの送信部品
 */
public class JFUMailSupportInterface extends JFUUrlConnection
{

	/** 正常 */
	public static final String SUCCESS = "00";

	/** 認証エラー */
	public static final String ERROR_CERTIFICATION = "13";

	/** パラメータ不正エラー */
	public static final String ERROR_PARAMETER = "92";

	/** システムエラー */
	public static final String ERROR_SYSTEM = "99";

	/** POPID取得キー */
	public static final String POP_ID = "POP_ID";

	/** POPIDパスワード取得キー */
	public static final String POP_ID_PWD = "POP_ID_PWD";

	/** メールサポート連携タイムアウト値取得キー */
	private static final String MAILSUPPORT_TIME_OUT = "FU_C_API_IF_MAILSUPPORT_TIME_OUT";

	/** メールサポート連携文字コード値取得キー */
	private static final String MAILSUPPORT_CHARCODE = "FU_C_API_IF_MAILSUPPORT_CHARCODE";

	/** リターンコードノード */
	private static final String RETURN_CODE_PATH = "/MSW00000_SEND/RETURN_CODE/text()";

	/** リクエストキー */
	private static final String REQUEST_KEY = "POPINF";

	/** レスポンスキー */
	private static final String RESPONSE_KEY_MACH_KEY = "^.*RESINF=";

	/** 送信XMLのヘッダー文字列 */
	private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>";

	/** 送信XMLのルート開始タグ */
	private static final String XML_MSW00000_RECEIVE_START = "<MSW00000_RECEIVE>";

	/** 送信XMLのPOPID開始タグ */
	private static final String XML_POP_ID_START = "<POP_ID>";

	/** 送信XMLのPOPID終了タグ */
	private static final String XML_POP_ID_END = "</POP_ID>";

	/** 送信XMLのPOPIDパスワード開始タグ */
	private static final String XML_POP_ID_PWD_START = "<POP_ID_PWD>";

	/** 送信XMLのPOPIDパスワード終了タグ */
	private static final String XML_POP_ID_PWD_END = "</POP_ID_PWD>";

	/** 送信XMLのルート終了タグ */
	private static final String XML_MSW00000_RECEIVE_END = "</MSW00000_RECEIVE>";

	/**
	 * POPIDパスワード認証を実施します。
	 *
	 * <br>
	 * @param inMap 送信情報
	 * @return 処理結果
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws IOException
	 * @throws TransformerException
	 * @throws InterruptedException
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws XPathExpressionException
	 */
	public static String getPopIdNinshoShokaiReqRslt(Map<String, Object> inMap) throws ParserConfigurationException, SAXException,
			IOException, TransformerException, InterruptedException, KeyManagementException, NoSuchAlgorithmException,
			XPathExpressionException
	{
		X31SWebLog.DEBUG_LOG.debug("【開始】メールサポートシステムの外部APIのIF");
		String result = execute(inMap, KEY_MAILSUPPORT_URL);
		X31SWebLog.DEBUG_LOG.debug("【終了】メールサポートシステムの外部APIのIF");
		return result;
	}

	/**
	 * メールサポートの外部APIを呼び出します。
	 *
	 * <br>
	 * @param inMap 送信情報
	 * @param urlKey 外部APIのURLキー
	 * @return 処理結果
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws IOException
	 * @throws TransformerException
	 * @throws InterruptedException
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws XPathExpressionException
	 */
	private static String execute(Map<String, Object> inMap, String urlKey) throws ParserConfigurationException, SAXException, IOException,
			TransformerException, InterruptedException, KeyManagementException, NoSuchAlgorithmException, XPathExpressionException
	{
		// 返却値の初期値に設定する。
		String result = ERROR_SYSTEM;

		// パラメータチェック
		if (isErrorParameter(inMap))
		{
			// 異常時

			result = ERROR_PARAMETER;
		}
		else
		{
			// 正常時

			// リクエストデータ作成
			String reqXml = createReqXmlString(inMap);

			// HTTPリクエスト(POST)
			result = communication(reqXml, urlKey);
		}
		return result;
	}

	/**
	 * POPID/PWDが設定されているかをチェックする。
	 *
	 * <br>
	 * @param inMap 送信情報
	 * @return true:パラメターエラーの場合、false:正常の場合
	 */
	private static boolean isErrorParameter(Map<String, Object> inMap)
	{
		// POPID
		if (!inMap.containsKey(POP_ID) || JFUWebCommon.isNull(inMap.get(POP_ID)))
		{
			return true;
		}

		// POPパスワード
		if (!inMap.containsKey(POP_ID_PWD) || JFUWebCommon.isNull(inMap.get(POP_ID_PWD)))
		{
			return true;
		}
		return false;
	}

	/**
	 * 送信用XMLデータを作成する。
	 * <br>
	 * @param inMap 送信情報
	 * @return 送信用XMLデータ
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws IOException
	 */
	private static String createReqXmlString(Map<String, Object> inMap) throws ParserConfigurationException, SAXException, IOException
	{
		StringBuffer xmlDataSb = new StringBuffer(DEFAULT_INITIAL_CAPACITY);
		xmlDataSb.append(XML_HEADER);
		xmlDataSb.append(XML_MSW00000_RECEIVE_START);
		xmlDataSb.append(XML_POP_ID_START).append(inMap.get(POP_ID)).append(XML_POP_ID_END);
		xmlDataSb.append(XML_POP_ID_PWD_START).append(inMap.get(POP_ID_PWD)).append(XML_POP_ID_PWD_END);
		xmlDataSb.append(XML_MSW00000_RECEIVE_END);

		DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = fact.newDocumentBuilder();
		String xmlData = xmlDataSb.toString();
		ByteArrayInputStream bis = new ByteArrayInputStream(xmlData.getBytes());
		db.parse(bis);
		return xmlData;
	}

	/**
	 * HTTPリクエスト(POST)を送信する。
	 *
	 * <br>
	 * @param data 送信用XMLデータ
	 * @param urlKey 外部APIのURLキー
	 * @return 処理結果
	 * @throws IOException
	 * @throws ParserConfigurationException
	 * @throws SAXException
	 * @throws TransformerException
	 * @throws InterruptedException
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws XPathExpressionException
	 */
	private static String communication(String data, String urlKey) throws IOException, ParserConfigurationException, SAXException,
			TransformerException, InterruptedException, KeyManagementException, NoSuchAlgorithmException, XPathExpressionException
	{

		String result = ERROR_SYSTEM;
		HttpURLConnection conn = null;
		String resXml = null;
		try
		{
			// リクエストタイムアウト値
			int timeOut = Integer.parseInt(JCCWebCommon.getApplicationConst(MAILSUPPORT_TIME_OUT));
			// HTTPリクエストエンコード
			String encoding = JCCWebCommon.getApplicationConst(MAILSUPPORT_CHARCODE);
			conn = createConnection(urlKey, timeOut);

			X31SWebLog.DEBUG_LOG.debug("【処理中】メールサポートシステムの外部APIのIF：URL：" + conn.getURL());
			X31SWebLog.DEBUG_LOG.debug("【処理中】メールサポートシステムの外部APIのIF：文字コード：" + encoding);
			X31SWebLog.DEBUG_LOG.debug("【処理中】メールサポートシステムの外部APIのIF：タイムアウト：" + timeOut);
			X31SWebLog.DEBUG_LOG.debug("【処理中】メールサポートシステムの外部APIのIF：送信データ：" + data);

			conn = connection(conn, REQUEST_KEY, data, encoding);
			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();
			}
			finally
			{
				if (null != bos)
				{
					bos.close();
				}
				if (null != bis)
				{
					bis.close();
				}
			}
			resXml = new String(outputByte, encoding);
		}
		finally
		{
			if (null != conn)
			{
				conn.disconnect();
			}
		}
		X31SWebLog.DEBUG_LOG.debug("【処理中】メールサポートシステムの外部APIのIF：外部APIからのレスポンス：" + resXml);
		resXml = resXml.replaceFirst(RESPONSE_KEY_MACH_KEY, EMPTY);
		ByteArrayInputStream bis = new ByteArrayInputStream(resXml.getBytes());
		DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = fact.newDocumentBuilder();
		Document xml = db.parse(bis);

		XPathFactory factory = XPathFactory.newInstance();
		XPath xpath = factory.newXPath();
		result = xpath.evaluate(RETURN_CODE_PATH, xml);

		X31SWebLog.DEBUG_LOG.debug("【処理中】メールサポートシステムの外部APIのIF：返却値：" + result);
		return result;
	}
}