/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKAddSptUtwkCC
*	ソースファイル名：JKKAddSptUtwkCC.java
*	作成者			：FAP
*	日付			：2012年02月10日
*＜機能概要＞
*	リモートサポート作業項目一覧照会（基準日指定）共通コンポーネント
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2012/02/10	FJ			新規作成
*	v4.00.00	2012/11/07	FJ)赤穂		【IT1-2012-0001723】対応
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
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.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 eo.ejb.cbs.cbsmsg.EKK0641D010CBSMsg;

/**
 * サポート内訳の登録を行う部品。
 * 
 * @author 富士通
 *
 */
public class JKKAddSptUtwkCC extends AbstractCommonComponent {

	/** テンプレートID(EKK0641D010) */
	private String TEMPLATE_ID = "EKK0641D010";

	/** サービスID */
	private static final String SERVICE_ID = "KKSV047703CC";

	/** 作業項目マップID */
	private static final String WORK_ID = "KKSV0477WORK01";

	/** 項目：更新年月日時分秒 */
	private static final String UPD_DTM = "upd_dtm";

	/** 項目：リモートサポート作業一覧リスト */
	private static final String RMT_SPRT_WRK_LIST = "support_work_list";

	/** CBSMsgのステータス項目 */
	private static final String STATUS = "status";

	/**
	 * サポート内訳を登録する。
	 * 
	 * @param handle セッションマネージャなどを持ったハンドル
	 * @param param モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param fixedText ユーザ任意文字列
	 * @return IRequestParameterReadWrite モデルグループ、コントロールマップを含むパラメータオブジェクト
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite addSptUtwk(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Exception {
		// リクエストパラメータからリモートサポート作業一覧情報を取得
		HashMap<String, Object> rmtSprtWrkMap = (HashMap<String, Object>)param.getData(SERVICE_ID);
		ArrayList<HashMap<String, Object>> rmtSprtWrkList = (ArrayList<HashMap<String, Object>>)rmtSprtWrkMap.get(RMT_SPRT_WRK_LIST);
		// 機能コード取得
		String func_code = (String)rmtSprtWrkMap.get("func_code");
		// 更新前更新年月日時分秒を作業用マップから取得
		Map<?,?> wkMap = param.getMappingWorkArea();
		HashMap<String, Object> workMap = (HashMap<String, Object>)wkMap.get(WORK_ID);
		String upd_bf = (String)workMap.get(UPD_DTM);
		// リモートサポート作業一覧マップの件数分繰り返し
		for(int i = 0; i < rmtSprtWrkList.size(); i++) {
			HashMap<String, Object> rmtSprtMap = rmtSprtWrkList.get(i);
			CAANMsg retMsg = execEKK0641D010(handle, param, workMap, rmtSprtMap, func_code);
			// 更新年月日時分秒を設定
			if(retMsg != null && !retMsg.isNull(UPD_DTM)) {
				upd_bf = retMsg.getString(UPD_DTM);

				// 下りマップ
				HashMap<String, Object> retWorkMap = new HashMap<String, Object>();
				retWorkMap.put(UPD_DTM, upd_bf);
				param.setData(WORK_ID, rmtSprtWrkList.get(i));
			}
		}
		return param;
	}


	/**
	 * チェック処理用のサービスインターフェイスを作成し返却する。
	 * @param handle 
	 * @param param
	 * @param fixedText
	 * @return
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	public HashMap<String, Object> getInvokeCBS(SessionHandle handle,IRequestParameterReadWrite param, String fixedText) throws RequestParameterException {
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		// SCインプット共通データ設定
		this.setSCInputCommonData(param, paramMap);
		HashMap<String, Object> inMap = (HashMap<String, Object>)(param.getData(fixedText));
		if (inMap == null) {
			return paramMap;
		}
		List<CAANMsg> templateList = new ArrayList<CAANMsg>();
		// リクエストパラメータからリモートサポート作業一覧情報を取得
		HashMap<String, Object> rmtSprtWrkMap = (HashMap<String, Object>)param.getData(SERVICE_ID);
		ArrayList<HashMap<String, Object>> rmtSprtWrkList = (ArrayList<HashMap<String, Object>>)rmtSprtWrkMap.get(RMT_SPRT_WRK_LIST);
		Map<?,?> wkMap = param.getMappingWorkArea();
		HashMap<String, Object> workMap = (HashMap<String, Object>)wkMap.get(WORK_ID);
		// リモートサポート作業一覧マップの件数分繰り返し
		for (HashMap<String, Object> map : rmtSprtWrkList) {
			templateList.add(setInMsgEKK0641D010(param, workMap, map, TEMPLATE_ID, "2"));
		}

		CAANMsg[] templates = (CAANMsg[])templateList.toArray(new CAANMsg[0]);
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);

		return paramMap;
	}


	/**
	 * サービスインターフェイスのエラー情報をマッピングする。
	 * @param param 
	 * @param templates
	 * @param returnCode
	 * @return
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	public IRequestParameterReadWrite editErrorInfo(IRequestParameterReadWrite param, CAANMsg[] templates, int returnCode) throws RequestParameterException {
		for (int i = 0; i < templates.length; i++) {
			CAANMsg template = templates[i];
			int templateStatus = template.getInt(STATUS);
			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<String, Object> inMap = (HashMap<String, Object>)param.getData(SERVICE_ID);
			ArrayList<HashMap<String, Object>> inMapList = (ArrayList<HashMap<String, Object>>)inMap.get(RMT_SPRT_WRK_LIST);

			HashMap<?, ?> mp = template.getHashMap();

			Iterator it = mp.keySet().iterator();
			while (it.hasNext()) {
				String key = (String)it.next();
				if (key.endsWith("_err"))
				{
					int keyIdx = key.lastIndexOf("_err");
					if (inMapList.get(i).containsKey(key.substring(0, keyIdx)))
					{
						inMapList.get(i).put(key, mp.get(key));
					}
				}
			}
		}
		return param;
	}

	/**
	 * SCインプット共通データ設定。
	 * @param param
	 * @param paramMap
	 * @throws RequestParameterException
	 */
	private void setSCInputCommonData (IRequestParameterReadWrite param, HashMap<String, Object> paramMap) throws RequestParameterException {
		/* SCインプット共通データ */
		// **********************************************
		// 【取得元：電文ヘッダ(ヘッダ)】
		// **********************************************
		// 電文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));
	}

	/**
	 * サービスインターフェイス共通部を設定する。
	 * 
	 * @param param リクエストパラメータ
	 * @param paramMap メッセージマップ
	 * @param tempId テンプレートＩＤ
	 * @param funcCd 機能コード
	 * @return template メッセージキャリア
	 * @throws RequestParameterException
	 */
	private void setInMsgCommon(IRequestParameterReadWrite param, CAANMsg template, String tempId, String funcCd) throws RequestParameterException {

		// テンプレートID
		template.set("templateID", tempId);

		// 機能コード
		template.set("func_code", funcCd);

		// オペレーションID
		Object operatorId = param.getControlMapData(SCControlMapKeys.OPERATOR_ID);
		template.set(JCMConstants.OPERATOR_ID_KEY, operatorId);

		// 運用日付
		Object operateDate = param.getControlMapData(SCControlMapKeys.OPE_DATE);
		template.set(JCMConstants.OPERATE_DATE_KEY, operateDate);

		// 運用日時
		Object operateDateTime = param.getControlMapData(SCControlMapKeys.OPE_TIME);
		template.set(JCMConstants.OPERATE_DATETIME_KEY, operateDateTime);

	}

	/**
	 * メッセージキャリアよりテンプレートリストを生成する。
	 * 
	 * @param paramMap メッセージ
	 * @param template メッセージキャリア
	 */
	private void setTemplateListKey(HashMap<String, Object> paramMap, CAANMsg template) {
		CAANMsg[] templates = new CAANMsg[1];
		templates[0] = template;
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, templates);


	}

	/**
	 * サポート内訳登録のメッセージ個別部を設定する。
	 * 
	 * @param param リクエストパラメータ
	 * @param workMap 作業項目用マップ
	 * @param tempId テンプレートＩＤ
	 * @param funcCd 機能コード
	 * @return paramMap メッセージマップ
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg setInMsgEKK0641D010(IRequestParameterReadWrite param, HashMap<String, Object> workMap, HashMap<String, Object> rmtSprtMap, String tempId, String funcCd) throws RequestParameterException {
		CAANMsg template = new CAANMsg("eo.ejb.cbs.cbsmsg.EKK0641D010CBSMsg");
		// サービスＩＦ共通部設定
		setInMsgCommon(param, template, tempId, funcCd);

		// リクエストパラメータより、作業用マップ、サポート内訳登録マップを取得
		Map<?,?> wkMap = param.getMappingWorkArea();
		HashMap<String, Object> kksv047703wkMap = (HashMap<String, Object>)wkMap.get(WORK_ID);

		template.set(EKK0641D010CBSMsg.SUPPORT_NO, (String)workMap.get("support_no"));
		template.set(EKK0641D010CBSMsg.RMT_SUPPORT_WORK_KMK_CD, (String)rmtSprtMap.get("rmt_support_work_kmk_cd"));
		template.set(EKK0641D010CBSMsg.RMT_SUPPORT_WORK_KMK_NM, (String)rmtSprtMap.get("rmt_support_work_kmk_nm"));
		template.set(EKK0641D010CBSMsg.RMT_SUPPORT_PRC, (String)rmtSprtMap.get("rmt_support_prc"));
		template.set(EKK0641D010CBSMsg.VSIT_SUPPORT_WORK_KMK_NM, "");
		template.set(EKK0641D010CBSMsg.VSIT_SUPPORT_WORK_AMNT, "");
		template.set(EKK0641D010CBSMsg.UPD_DTM, (String)kksv047703wkMap.get("upd_dtm"));

		return template;
	}

	/**
	 * サポート内訳登録サービスIFを実行する。
	 * @param handle
	 * @param param
	 * @param workMap
	 * @param funcCd
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	private CAANMsg execEKK0641D010(SessionHandle handle, IRequestParameterReadWrite param, HashMap<String, Object> workMap, HashMap<String, Object> rmtSprtMap, String funcCd) throws Exception {
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		Map<?, ?> result = null;

		// メッセージ共通部設定
		setSCInputCommonData(param, paramMap);
		// サービスＩＦ設定
		setTemplateListKey(paramMap, setInMsgEKK0641D010(param, workMap, rmtSprtMap,  TEMPLATE_ID, funcCd));

		// ■サービスIF実行
		result = scCall.run(paramMap, handle);

		// 処理結果の判定
		CAANMsg[] templates = (CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY);

		// 取得したリターンコード、ステータスの内容を見て異常かどうかの判断をする。
		String rtnCode = result.get(JCMConstants.RET_CD_INT_KEY).toString();

		// エラー情報の転記
		editErrorInfo(param, templates, (Integer)result.get(JCMConstants.RET_CD_INT_KEY));

		// エラー情報のマップを取得
		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));

		int status = templates[0].getInt(STATUS);
		// 以上の場合SCCallExceptionを生成してスローする
		if (!("0".equals(rtnCode) && 0 == status)) {
			throw new SCCallException("戻り値不正", rtnCode, status);
		}
		return (((CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY)))[0];
	}

}
