/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：JFUTicketUseShinIraiCC
*   ソースファイル名：JFUTicketUseShinIraiCC.java
*   作成者          ：FJ
*   日付            ：2016年05月31日
*＜機能概要＞
*   チケット利用申請依頼の共通コンポーネント
*＜修正履歴＞
*   バージョン  修正日      修正者      修正内容
*	v26.00.00	2016/05/31	FJ) 張本	【ANK-2687-00-00】プレミアムサポート施策
*	v26.00.01	2016/07/14	FJ）張本	【IT1-2016-0000095】外部IF KKIFE334 項目名間違い
*	v26.00.02	2016/08/22	FJ）張本	【ST-2016-0000029】マイナーエラー時のログレベル変更
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import static com.fujitsu.futurity.bp.custom.common.JCKPmpCommonUtil.printDebugLog;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fujitsu.futurity.bp.x21.bpm.ServiceComponentRequestInvoker;
import com.fujitsu.futurity.bp.x21.bpm.db.SessionHandle;
import com.fujitsu.futurity.bp.x21.bpm.exception.RequestParameterException;
import com.fujitsu.futurity.bp.x21.bpm.parameter.IRequestParameterReadWrite;
import com.fujitsu.futurity.bp.x21.cc.AbstractCommonComponent;
import com.fujitsu.futurity.common.JCCSuperComExecUtil;
import com.fujitsu.futurity.common.JCCSyslogFormat;
import com.fujitsu.futurity.common.JCMConstants;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;
import com.fujitsu.futurity.mapping.bp.common.TemplateErrorUtil;
import com.fujitsu.futurity.model.base.CAANMsg;
import com.fujitsu.futurity.model.common.JCMAPLConstMgr;

import eo.ejb.cbs.cbsmsg.EKKA0050002CBSMsg;

/**
 *  チケット利用申請依頼部品。<p>
 * <BR>
 * @author 富士通
 */
public class JFUTicketUseShinIraiCC extends AbstractCommonComponent
{
	/** チケット利用申請依頼 */
	private static final String TEMPLATE_ID_EKKA0050002 = "EKKA0050002";

	/** SYSID**/
	private static final String SYSID = "sysid";
	/** サービス契約番号**/
	private static final String SVC_KEI_NO = "svc_kei_no";
	/** 施策コード */
	private static final String SISAK_CD = "sisak_cd";
	/** キャンペーン登録契機コード */
	private static final String CMP_ADD_OPTNTY_CD = "cmp_add_optnty_cd";
	/**キャンペーン登録契機対象キー1 */
	private static final String CMP_ADD_OPTNTY_TG_KEY_1 = "cmp_add_optnty_tg_key_1";
	/**キャンペーン登録契機対象キー2 */
	private static final String CMP_ADD_OPTNTY_TG_KEY_2 = "cmp_add_optnty_tg_key_2";
	/**キャンペーン登録契機対象キー3 */
	private static final String CMP_ADD_OPTNTY_TG_KEY_3 = "cmp_add_optnty_tg_key_3";
	/**キャンペーン登録契機対象キー4 */
	private static final String CMP_ADD_OPTNTY_TG_KEY_4 = "cmp_add_optnty_tg_key_4";
	/**キャンペーン登録契機対象キー1 */
	private static final String CMP_ADD_OPTNTY_TG_KEY_5 = "cmp_add_optnty_tg_key_5";

	/** 日時書式(yyyyMMddHHmmssSSS) */
	private static final String FMT_YMDHMSS = "yyyyMMddHHmmss";
	/** メッセージ区分 */
	private static final String WAR = "WAR";
	/** エラー項目接頭辞 */
	private static final String PREFIX_KEY_ITEM = "key_";
	/** エラー項目末尾辞 */
	private static final String PREFIX_ERR_ITEM = "_err";
	/** CC エラーメッセージ 接頭辞 */
	private static final String KEY_RETURN_MESSAGE = "RETURN_MESSAGE_";
	/** ステータスフォーマット */
	private static final String STATUS_FORMAT = "%1$04d";

	/** 外部インターフェイスID **/
	private static final String KKIFE334 = "KKIFE334";
	/** APIメッセージID **/
	private static final String API_MSG_ID = "EKF1930-KW";

	/**
	 * チケット利用申請依頼処理を行う。
	 * 
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText サービスメッセージ
	 * @return IRequestParameterReadWriteリクエストパラメータ管理クラス
	 * @throws Throwable 例外
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite execute(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable
	{
		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない）
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();

		// ユーザデータ情報
		HashMap<String, Object> paramMap = (HashMap<String, Object>)param.getData(fixedText);
		// チケット申請リスト
		List<HashMap<String, Object>> ticketList = (List<HashMap<String, Object>>)paramMap.get("ticket_use_shin_irai_list");

		for (HashMap ticketMap : ticketList)
		{
			Object[][] ekk0050002InMsg =
					{ { EKKA0050002CBSMsg.TEMPLATEID, TEMPLATE_ID_EKKA0050002 }, { EKKA0050002CBSMsg.FUNC_CODE, "1" },
							{ EKKA0050002CBSMsg.SYSID, (String)paramMap.get(SYSID) },
							{ EKKA0050002CBSMsg.SVC_KEI_NO, (String)paramMap.get(SVC_KEI_NO) },
							{ EKKA0050002CBSMsg.SISK_CD, (String)ticketMap.get(SISAK_CD) },
							{ EKKA0050002CBSMsg.CP_ADD_KEIKI_CD, (String)ticketMap.get(CMP_ADD_OPTNTY_CD) },
							{ EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_1, (String)ticketMap.get(CMP_ADD_OPTNTY_TG_KEY_1) },
							{ EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_2, (String)ticketMap.get(CMP_ADD_OPTNTY_TG_KEY_2) },
							{ EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_3, (String)ticketMap.get(CMP_ADD_OPTNTY_TG_KEY_3) },
							{ EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_4, (String)ticketMap.get(CMP_ADD_OPTNTY_TG_KEY_4) },
							{ EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_5, (String)ticketMap.get(CMP_ADD_OPTNTY_TG_KEY_5) } };

				callSC(handle, scCall, param, fixedText, ekk0050002InMsg);

		}
		return param;
	}

	/**
	 * SC(サービスインターフェイス）を呼び出す。
	 * 
	 * @param handle セッションハンドル
	 * @param scCall SC呼出し部品
	 * @param param リクエストパラメータ
	 * @param dataMapKey パラメータキー
	 * @param mappingData マッピングデータ
	 * @return CAANMsg 実行結果
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg callSC(SessionHandle handle, ServiceComponentRequestInvoker scCall, IRequestParameterReadWrite param, String dataMapKey,
			Object[][] mappingData) throws Exception
	{
		HashMap<String, Object> paramMap = getInvokeCBS(param, mappingData);

		printDebugLog("■■■チケット申請依頼API呼び出し開始" + paramMap);
		Map<?, ?> result = scCall.run(paramMap, handle);
		printDebugLog("■■■チケット申請依頼API呼び出し完了" + result);

		CAANMsg[] templates = (CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg msg = templates[0];

		// リターンコード取得
		Object return_code = result.get(JCMConstants.RET_CD_INT_KEY);
		int status = msg.getInt(JCMConstants.STATUS_INT_KEY);

		editErrorInfoCom(param, templates, (Integer)return_code, dataMapKey, mappingData);

		//エラー情報のマップを取得
		ArrayList<Object> errList = (ArrayList<Object>)param.getControlMapData(SCControlMapKeys.ERROR_INFO);
		if (errList == null)
		{
			errList = new ArrayList<Object>();
		}

		// コントロールマップに設定
		param.setControlMapData(SCControlMapKeys.ERROR_INFO, TemplateErrorUtil.getErrorInfo(result, errList));

		// 異常の場合、マイナーエラーを出力して処理を続行する
		if (!("0".equals(return_code.toString()) && 0 == status))
		{
			String apiRetCd = msg.getString(EKKA0050002CBSMsg.API_RSLT_CD);
			
			if (apiRetCd == null)
			{
				apiRetCd = "9000 (HTTPステータス:500)";
			}
			// メッセージログ（システムログ）にメッセージID「EKF1930-KW」に該当するメッセージを出力する
			String message =
					"チケット利用申請依頼でエラーが発生した為、正常にチケット利用情報が登録できませんでした。" 
							+ "(KEY：識別コード=TASV000301SC" 
							+ "：SYSID=" + msg.getString(EKKA0050002CBSMsg.SYSID) 
							+ "：サービス契約番号=" + msg.getString(EKKA0050002CBSMsg.SVC_KEI_NO) 
							+ "：施策コード=" + msg.getString(EKKA0050002CBSMsg.SISK_CD) 
							+ "：キャンペーン登録契機コード=" + msg.getString(EKKA0050002CBSMsg.CP_ADD_KEIKI_CD) 
							+ "：キャンペーン登録契機対象キー1=" + msg.getString(EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_1) 
							+ "：キャンペーン登録契機対象キー2=" + msg.getString(EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_2) 
							+ "：キャンペーン登録契機対象キー3=" + msg.getString(EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_3) 
							+ "：キャンペーン登録契機対象キー4=" + msg.getString(EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_4) 
							+ "：キャンペーン登録契機対象キー5=" + msg.getString(EKKA0050002CBSMsg.CP_ADD_KEIKI_KEY_5) 
							+ "：API処理結果コード=" + apiRetCd + ")";
			printSyslog4Err(KKIFE334, API_MSG_ID, message);
		}
		return msg;
	}

	/**
	 * CAANMsgに必要なデータのマッピング処理を行います。
	 * 
	 * @param param リクエストパラメータ
	 * @param mappingData マッピングデータ
	 * @return HashMap<String, Object> 結果マップ
	 * @throws RequestParameterException
	 */
	private HashMap<String, Object> getInvokeCBS(IRequestParameterReadWrite param, Object[][] mappingData) throws RequestParameterException
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();

		// 【取得元：電文ヘッダ(ヘッダ)】
		// 電文ID
		paramMap.put(JCMConstants.TRANZACTION_ID_KEY, param.getTelegramID());
		// ユースケースID
		paramMap.put(JCMConstants.USECASE_ID_KEY, param.getUsecaseID());
		// オペレーションID
		paramMap.put(JCMConstants.OPERATION_ID_KEY, param.getOperationID());
		// サービス呼び出し区分
		paramMap.put(JCMConstants.CALL_TYPE_KEY, param.getCallType());

		// 【取得元：ユーザエリア(コントロールマップ)】
		// 依頼先ホスト名
		paramMap.put(JCMConstants.CLIENT_HOST_NAME_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTNAME));
		// 依頼元IPアドレス
		paramMap.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		// 依頼元画面ID
		paramMap.put(JCMConstants.INVOKE_GAMEN_ID_KEY, param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		// オペレータID
		paramMap.put(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));

		String svcIf = (String)mappingData[0][1];

		CAANMsg template = new CAANMsg(String.format("eo.ejb.cbs.cbsmsg.%sCBSMsg", svcIf));

		// オペレータID
		template.set(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));
		// 運用日付
		template.set(JCMConstants.OPERATE_DATE_KEY, param.getControlMapData(SCControlMapKeys.OPE_DATE));
		// 運用日時
		template.set(JCMConstants.OPERATE_DATETIME_KEY, param.getControlMapData(SCControlMapKeys.OPE_TIME));

		for (int i = 0; i < mappingData.length; i++)
		{
			if ("".equals(mappingData[i][1]))
			{
				template.setNull((String)mappingData[i][0]);
			}
			else
			{
				template.set((String)mappingData[i][0], mappingData[i][1]);
			}
		}

		CAANMsg[] templates = new CAANMsg[1];
		templates[0] = template;
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);

		return paramMap;
	}

	/**
	 * エラー情報を編集する。
	 * 
	 * @param param リクエストパラメータ
	 * @param templates CAANMsgクラス配列
	 * @param returnCode リターンコード
	 * @param dataMapKey パラメータキー
	 * @param mappingData マッピングデータ
	 * @return IRequestParameterReadWrite
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private IRequestParameterReadWrite editErrorInfoCom(IRequestParameterReadWrite param, CAANMsg[] templates, int returnCode, String dataMapKey,
			Object[][] mappingData) throws RequestParameterException
	{
		// 本来はサービスインターフェイス分の処理が必要
		CAANMsg template = templates[0];
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);

		if (returnCode != 0)
		{
			templateStatus = 9000;
		}

		if (JCMAPLConstMgr.getString(KEY_RETURN_MESSAGE + String.format(STATUS_FORMAT, templateStatus)) == null)
		{
			templateStatus = 0;
		}

		int bpStatus = 0;
		Object obj = param.getControlMapData(SCControlMapKeys.RETURN_CODE);
		if (obj == null)
		{
			bpStatus = -1;
		}
		else
		{
			bpStatus = Integer.parseInt((String)param.getControlMapData(SCControlMapKeys.RETURN_CODE));
		}

		if (templateStatus > bpStatus)
		{
			// BPにサービスコンポーネントのステータスを設定する。
			String formatStatus = String.format(STATUS_FORMAT, templateStatus);
			String message = JCMAPLConstMgr.getString(KEY_RETURN_MESSAGE + formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
		}

		HashMap<String, String> inMap = null;

		// ユーザデータ情報
		inMap = (HashMap<String, String>)param.getData(dataMapKey);

		for (int i = 0; i < mappingData.length; i++)
		{
			if (((String)mappingData[i][0]).startsWith(PREFIX_KEY_ITEM))
			{
				if (!template.isNull(mappingData[i][0] + PREFIX_ERR_ITEM))
				{
					if (!inMap.containsKey(mappingData[i][0] + PREFIX_ERR_ITEM))
					{
						inMap.put(mappingData[i][0] + PREFIX_ERR_ITEM, template.getString(mappingData[i][0] + PREFIX_ERR_ITEM));
					}
				}
			}
		}
		return param;
	}

	/**
	 * シスログ出力
	 * @param proId プログラムID
	 * @param msgId メッセージID
	 * @param msg   メッセージ文字列
	 */
	private static void printSyslog4Err(String proId, String msgId, String msg)
	{

		String sysdate = new SimpleDateFormat(FMT_YMDHMSS).format(new Date(System.currentTimeMillis()));
		HashMap<String, Object> propMap = new HashMap<String, Object>();

		propMap.put(JCCSuperComExecUtil.EXEC_BUFF_SIZE, JCMAPLConstMgr.getString(JCCSuperComExecUtil.EXEC_BUFF_SIZE));
		propMap.put(JCCSuperComExecUtil.EXEC_PERMIT_MEMORY, JCMAPLConstMgr.getString(JCCSuperComExecUtil.EXEC_PERMIT_MEMORY));
		propMap.put(JCCSyslogFormat.SYSLOG_FOMAT_PTN_KEY, JCMAPLConstMgr.getString(JCCSyslogFormat.SYSLOG_FOMAT_PTN_KEY));
		propMap.put(JCCSyslogFormat.SYSLOG_MAILING_ID_KEY, JCMAPLConstMgr.getString(JCCSyslogFormat.SYSLOG_MAILING_ID_KEY));
		propMap.put(JCCSyslogFormat.SYSLOG_OUT_DIR_OPTION, JCMAPLConstMgr.getString(JCCSyslogFormat.SYSLOG_OUT_DIR_OPTION));
		JCCSyslogFormat.logger(proId, msgId, sysdate, msg, WAR, propMap);
	}

}