/*********************************************************************
 * All Rights reserved,Copyright (c) K-Opticom, 2011
 **********************************************************************
 *＜プログラム内容＞
 *   システム名      ：eo顧客基幹システム
 *   モジュール名    ：JCKCommonCC
 *   ソースファイル名：JCKCommonCC.java
 *   作成者          ：FJ
 *   日付            ：2015年05月28日
 *＜機能概要＞
 *   マルチセッションを登録する。
 *＜修正履歴＞
 *   バージョン  修正日       修正者      修正内容
 *   v16.00.00   2015/05/28  FJ) 酒井    ANK-2480-00-00 新規作成
 **********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
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.bp.x21.cc.exception.CCException;
import com.fujitsu.futurity.bp.x21.cc.exception.SCCallException;
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 com.fujitsu.futurity.model.ejb.common.JSYejbLog;

import eo.ejb.cbs.cbsmsg.ECKA9030001CBSMsg;

public abstract class JCKCommonCC extends AbstractCommonComponent {

	/** 機能コード */
	protected static final String FUNC_CD_1 = "1";
	protected static final String FUNC_CD_2 = "2";
	
	/** SC呼び出し部品 */
	protected ServiceComponentRequestInvoker scCall = null;
	/** セッションハンドル */
	protected SessionHandle handle = null;
	/** 業務データ取得用I/F */
	protected IRequestParameterReadWrite param = null;
	/** 実行時用固定文字列 **/
	protected String fixedText = null;
	/** オンライン運用日付 */
	protected String opeDate = null;
	/** 内部map */
	protected Map<String, Object> ccWorkMap = null;

	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>デバッグログを出力する<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param dumpObj 出力するオブジェクト
	 */
	protected void printlnEjbLog(Object dumpObj) {
		JSYejbLog.println(JSYejbLog.DEBUG, this.getClass(), dumpObj, null, null, null);
	}

	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>null又は空文字の場合、trueを返却する<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param str 検査対象文字列
	 * @return true:null、又は空文字／false:左記以外
	 */
	protected boolean isNullBlank(String tg){
		return tg == null || "".equals(tg) ? true : false;
	}
	
	/**
	 * <dl>
	 * <dt>処理概要：
	 * <dd>サービスコンポーネント実行後に、IRequestParameterReadWriteにエラー情報をマッピング<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param param	      業務データ取得・書込用I/F
	 * @param templates	  CAANMsgクラス配列
	 * @param returnCode リターンコード
	 * @param mapName    SCマップ名
	 * @return 業務データ取得・書込用I/F
	 */
	@SuppressWarnings( { "unchecked", "cast", "boxing" })
	public IRequestParameterReadWrite editErrorInfo(IRequestParameterReadWrite param,
			CAANMsg[] templates, int returnCode, String mapName) throws Throwable {
		
		int templateStatus = 0;
		if (returnCode != 0) {
			templateStatus = 9000;
		}
		if (JCMAPLConstMgr.getString("RETURN_MESSAGE_" + String.format("%1$04d", 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("%1$04d", templateStatus);
			String message = JCMAPLConstMgr.getString("RETURN_MESSAGE_" + formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_CODE, formatStatus);
			param.setControlMapData(SCControlMapKeys.RETURN_MESSAGE, message);
		}

		HashMap inMap = null;

		// 作業項目領域
		Map workMap = (Map) param.getMappingWorkArea();
		if (workMap == null) {
			workMap = new HashMap();
			param.setMappingWorkArea(workMap);
		}

		/* ユーザデータ情報 */
		inMap = (HashMap) param.getData(mapName);
		if (inMap == null) {
			inMap = new HashMap();
			param.setData(mapName, inMap);
		}
		
		String svcIf = null;
		if (svcIf == null) {
			return param;
		}
		
		return param;
	}

	/**
	 * <dl>
	 * <dt>処理概要：
	 * <dd>サービスコンポーネント実行後に、IRequestParameterReadWriteに必要なデータをマッピング<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param result   サービスIFリスト
	 * @param param    業務データ取得・書込用I/F
	 * @param mapName  SCマップ名
	 * @return
	 * @throws Throwable
	 */
	@SuppressWarnings( { "unchecked", "cast", "boxing" })
	public IRequestParameterReadWrite editResultRP(Map<?, ?> result,
			 IRequestParameterReadWrite param, String mapName) throws Throwable {

		// SCからの戻り値からCAANMsgを取得する。
		CAANMsg[] templates = (CAANMsg[]) result.get(JCMConstants.TEMPLATE_LIST_KEY);

		// リターンコード取得
		Object return_code = result.get(JCMConstants.RET_CD_INT_KEY);

		// 作業領域の取得
		Map workMap = (Map) param.getMappingWorkArea();
		if (workMap == null) {
			workMap = new HashMap();
			param.setMappingWorkArea(workMap);
		}

		// 結果を詰めるマップを取得。
		HashMap dataMap = null;

		/* 業務データ設定 */
		dataMap = (HashMap) param.getData(mapName);
		if (dataMap == null) {
			dataMap = new HashMap();
			param.setData(mapName, dataMap);
		}

		// エラー情報の設定
		param = editErrorInfo(param, templates, (Integer) return_code, mapName);

		// エラー情報のマップを取得
		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));
		
		return param;
	}
	
	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>フィールドを初期化<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param param
	 * @param fixedText
	 * @throws RequestParameterException
	 */
	protected void initSetUp(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
			throws RequestParameterException {
		
		// セッションハンドル
		this.handle = handle;
		
		// 業務データ取得用I/F
		this.param = param;
		
		// 実行時用固定文字列 
		this.fixedText = fixedText;

		// オンライン運用日付
		this.opeDate = JCCBPCommon.getOpeDate(null);
		
		// SC呼び出し部品
		this.scCall = new ServiceComponentRequestInvoker();
		
		// 内部map
		this.ccWorkMap = new HashMap<String, Object>();
	}
	
	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>keyに紐づく引数を内部mapへ保持（必須項目用）<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param  key 
	 * @throws CCException 
	 * @throws RequestParameterException 
	 */
	@SuppressWarnings("unchecked")
	protected void setWorkParamHissu(String key) throws CCException, RequestParameterException {
		
		HashMap<String, Object> inMap = (HashMap<String, Object>) this.param.getData(this.fixedText);
		
		String obj = (String) inMap.get(key);
		
		if (obj == null || "".equals(obj)) {
			printlnEjbLog(key + "=NULL");
			throw new CCException(key + "=NULL", new Exception());
		}

		printlnEjbLog(key + "=" + obj);
		this.ccWorkMap.put(key, obj);
	}

	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>keyに紐づく引数を内部mapへ保持（任意項目用）<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param  key 
	 * @throws CCException 
	 * @throws RequestParameterException 
	 */
	@SuppressWarnings("unchecked")
	protected void setWorkParam(String key) throws CCException, RequestParameterException {
		
		HashMap<String, Object> inMap = (HashMap<String, Object>) this.param.getData(this.fixedText);
		
		String obj = (String) inMap.get(key);
		
		printlnEjbLog(key + "=" + obj);
		this.ccWorkMap.put(key, obj);
			
	}

	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>keyに紐づく引数を内部mapへ保持<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param  key 
	 * @throws CCException 
	 * @throws RequestParameterException 
	 */
	@SuppressWarnings("unchecked")
	protected void setterWorkParamList(String key) throws CCException, RequestParameterException {
		
		HashMap<String, Object> inMap = (HashMap<String, Object>) this.param.getData(this.fixedText);
		
		ArrayList obj = (ArrayList) inMap.get(key);
		
		if (obj == null || obj.size() == 0) {
			printlnEjbLog(key + "=NULL");
			throw new CCException(key + "=NULL", new Exception());
		}
		
		printlnEjbLog(key + "=" + obj);
		this.ccWorkMap.put(key, obj);
	}

	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>SCインプット共通データ設定<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @return パラメータマップ
	 * @throws Throwable
	 */
	protected HashMap<String, Object> createSCInputData() throws Throwable {
		
		HashMap<String, Object> map = new HashMap<String, Object>();
		// 電文ID
		map.put(JCMConstants.TRANZACTION_ID_KEY, this.param.getTelegramID());
		// ユースケースID
		map.put(JCMConstants.USECASE_ID_KEY, this.param.getUsecaseID());
		// オペレーションID
		map.put(JCMConstants.OPERATION_ID_KEY, this.param.getOperationID());
		// サービス呼び出し区分
		map.put(JCMConstants.CALL_TYPE_KEY, this.param.getCallType());

		// 依頼先ホスト名
		map.put(JCMConstants.CLIENT_HOST_NAME_KEY, this.param.getControlMapData(SCControlMapKeys.REQ_HOSTNAME));
		// 依頼元IPアドレス
		map.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, this.param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		// 依頼元画面ID
		map.put(JCMConstants.INVOKE_GAMEN_ID_KEY, this.param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		// オペレータID
		map.put(JCMConstants.OPERATOR_ID_KEY, this.param.getControlMapData(SCControlMapKeys.OPERATOR_ID));
		
		return map;
	}

	/**
	 * <dl>
	 * <dt>処理概要：
	 * <dd>S/IF呼出時の共通情報を設定する<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param msg        対象クラス
	 * @param contents 	  対応クラスのフィールド列挙
	 * @param templateId テンプレートID
	 * @param funcCd     機能コード
	 * @return
	 * @throws Throwable 
	 */
	protected CAANMsg createTemplate(CAANMsg msg, Object[][] contents, String templateId, String funcCd) throws Throwable {
		
		CAANMsg template = msg;
		
		// 持ちうるフィールドにNullマッピングで埋める
		for (int i = 0; i < contents.length; i++) {
		
			Object element = null;
		
			// キーに該当する箇所の取得
			element = contents[i][0];
			// Nullでマッピング
			template.setNull((String) element);
		}
		
		// オペレータID
		Object operatorId = this.param.getControlMapData(SCControlMapKeys.OPERATOR_ID);
		template.set(JCMConstants.OPERATOR_ID_KEY, operatorId);
		
		// 運用日付
		Object operateDate = this.param.getControlMapData(SCControlMapKeys.OPE_DATE);
		template.set(JCMConstants.OPERATE_DATE_KEY, operateDate);
		
		// 運用日時
		Object operateDateTime = this.param.getControlMapData(SCControlMapKeys.OPE_TIME);
		template.set(JCMConstants.OPERATE_DATETIME_KEY, operateDateTime);
		
		// テンプレートID
		template.set(ECKA9030001CBSMsg.TEMPLATEID, templateId);
		
		// 機能コード
		template.set(ECKA9030001CBSMsg.FUNC_CODE, funcCd);
		
		return template;
	}

	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>呼び出したサービスIFの処理結果を判定する<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param result サービスIFリスト
	 * @throws Throwable
	 */
	@SuppressWarnings("boxing")
	protected void checkExecutionResult(Map<?, ?> result) throws Throwable {

		// 取得したリターンコード、ステータスの内容を見て異常かどうかの判断をする。
		String rtnCode = result.get(JCMConstants.RET_CD_INT_KEY).toString();
		CAANMsg[] templates = (CAANMsg[]) result.get(JCMConstants.TEMPLATE_LIST_KEY);
		Integer status = templates[0].getInt(JCMConstants.STATUS_INT_KEY);

		// 異常の場合、SCCallExceptionを生成してスローする
		if (!("0".equals(rtnCode) && 0 == status.intValue())) {
			SCCallException scCallEx = new SCCallException("戻り値不正", rtnCode, status);
			throw scCallEx;
		}
	}

	/**
	 * 
	 * <dl>
	 * <dt>処理概要：
	 * <dd>サービスIFの結果を取得する<BR>
	 * <dt>処理補足：
	 * <dd>
	 * </dl>
	 * 
	 * @param rsltMap       サービスIFリスト
	 * @return templateList 結果が格納されたリスト
	 * @throws Throwable
	 */
	protected CAANMsg getRsltList(Map<?, ?> rsltMap) {
		return ((CAANMsg[]) rsltMap.get(JCMConstants.TEMPLATE_LIST_KEY))[0];
	}
}