/*********************************************************************
*	All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名		：eo顧客基幹システム
*	モジュール名	：JKKSV0674012MappingCC
*	ソースファイル名：JKKSV0674012MappingCC.java
*	作成者			：富士通
*	日付			：2012年09月05日
*＜機能概要＞
*	マッピングCCです。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2012/09/05	FJ			新規作成
*
**********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.fujitsu.futurity.bp.custom.constant.KKSV0699_KKSV0699OP;
import com.fujitsu.futurity.bp.custom.constant.KKSV0699_KKSV0699OP_WORK;
import com.fujitsu.futurity.bp.custom.constant.KKSV0699_KKSV0699OP_WORK_EKK0081A010CBSMsg1List;
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.common.constant.JPCModelConstant;
import eo.ejb.cbs.cbsmsg.EKK0011D020CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0321B002CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0321B002CBSMsg1List;

public class JKKSV0674012MappingCC extends AbstractCommonComponent
{
	
	/** 作業マップ名 */
	private static final String CC_WORK_AREA_NAME_MSKM = "JKKAddMskmServiceCCWork";

	/** 作業マップ名 */
	private static final String CC_WORK_AREA_NAME_MSKM_LIST = "JKKAddMskmServiceCCWorkList";
	
	/**
	 * CCへのマッピング処理を行います
	 * <br>
	 * @param handle
	 * @param param
	 * @param fixedText
	 * @return
	 * @throws Throwable
	 */
	public IRequestParameterReadWrite execute(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable
	{
		// eo光ネットサービス契約料金コース変更ＣＣ オプションサービス契約＜ISP＞登録のMap取得
		HashMap<String, Object> kksv020215scMap =  (HashMap<String, Object>) param.getData("KKSV020215SC");
		
		// eo光ネットサービス契約料金コース変更ＣＣ サービス契約一意照会のMap取得
		HashMap<String, Object> kksv069902scMap =  (HashMap<String, Object>) param.getData("KKSV069902SC");
		
		// eo光ネットサービス契約料金コース変更ＣＣ ワークマップの取得
		Map workAreaMap = param.getMappingWorkArea();
		HashMap<String, Object> workMap = (HashMap<String, Object>)workAreaMap.get(KKSV0699_KKSV0699OP.WORK);
		if (workMap == null)
		{
			workMap = new HashMap<String, Object>();
			workAreaMap.put(KKSV0699_KKSV0699OP.WORK, workMap);
		}
		
		
		
		String svcKeiNo = "";
		if(kksv069902scMap!=null){
			svcKeiNo = (String) kksv069902scMap.get("key_svc_kei_no");
		}
		
		String seikyKeiNo = "";
		// S-IF：EKK0321B002 課金先一覧照会（請求契約番号/サービス契約番号）
		HashMap<String, Object> inputMap = new HashMap<String, Object>();
		inputMap.put(JCMConstants.FUNC_CODE_KEY, JPCModelConstant.FUNC_CD_1);
		inputMap.put("key_svc_kei_no", svcKeiNo);
		CAANMsg[] retMsgs = (CAANMsg[])runEKK0321B002(handle, param, inputMap, fixedText);
		if (retMsgs.length > 0)
		{
			seikyKeiNo = retMsgs[0].getString(EKK0321B002CBSMsg1List.SEIKY_KEI_NO);
		}
		
		if(kksv020215scMap!=null){
			// 請求契約番号の設定
			kksv020215scMap.put("seiky_kei_no", seikyKeiNo);
		}
		
		//更新年月日
		HashMap<String, Object> dtmWorkMap = (HashMap<String, Object>) param.getData("KKSV0674Work");
		if(dtmWorkMap!=null){
			//ＫＫ２１１１更新年月日時分秒
			workMap.put(KKSV0699_KKSV0699OP_WORK.KK2111_UPD_DTM, dtmWorkMap.get("eoh_nt_svc_kei_upd_dtm_bef"));
		}
		
		// 申込明細番号をワークに設定
		workMap.put("mskm_dtl_no", getMskmDtlWorkMapValue(param, "mskm_dtl_no_net"));
		// 異動区分をワークに設定
		workMap.put("ido_div", "00019");
		
		
		
		return param;
	}
	
	/**
	 * 作業マップ（申込明細）の値を取得します。
	 * 
	 * <br>
	 * @param param
	 * @param key
	 * @return 取得した値
	 * @throws RequestParameterException
	 */
	@SuppressWarnings("unchecked")
	private String getMskmDtlWorkMapValue(IRequestParameterReadWrite param, String key) throws RequestParameterException
	{
		// 作業領域の取得
		Map workMap = (Map)param.getMappingWorkArea();
		HashMap inMap = null;
		HashMap workDataMap_Mskm = null;
		String result = null;

		if (workMap != null)
		{
			workDataMap_Mskm = (HashMap)workMap.get(CC_WORK_AREA_NAME_MSKM);
			if (workDataMap_Mskm != null)
			{
				ArrayList inList1 = ((ArrayList)workDataMap_Mskm.get(CC_WORK_AREA_NAME_MSKM_LIST));
				int devCnt = inList1 != null ? inList1.size() : 0;
				for (int i = 0; i < devCnt; i++)
				{
					inMap = (HashMap)(inList1).get(i);

					if (inMap != null)
					{
						result = (String)inMap.get(key);
					}

					if ("".equals(result) || result == null)
					{
						result = null;
					}
					else
					{
						break;
					}
				}
			}
		}

		return result;
	}
	
	/**
	 * @param handle
	 * @param param
	 * @param templateId
	 * @param inMap
	 * @return CAANMsg[]
	 * @throws Throwable
	 */
	private Object runEKK0321B002(SessionHandle handle, IRequestParameterReadWrite param, Map<String, Object> inMap, String fixedText) throws Throwable
	{
		HashMap<String, Object> paramMap = new HashMap<String, Object>();

		// 【取得元：電文ヘッダ(ヘッダ)】
		paramMap.put(JCMConstants.TRANZACTION_ID_KEY, param.getTelegramID());
		paramMap.put(JCMConstants.USECASE_ID_KEY, param.getUsecaseID());
		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));
		paramMap.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		paramMap.put(JCMConstants.INVOKE_GAMEN_ID_KEY, param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		paramMap.put(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));

		CAANMsg template = new CAANMsg("eo.ejb.cbs.cbsmsg.EKK0321B002CBSMsg");
		fillCAANMSGNullMapping(template, new EKK0321B002CBSMsg().getContents());
		
		template.set(JCMConstants.TEMPLATE_ID_KEY, "EKK0321B002");
		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));

		if (inMap != null)
		{
			Set<String> setKey = inMap.keySet();
			Iterator<String> iter = setKey.iterator();
			while (iter.hasNext())
			{
				String key = iter.next();
				if (!isEmptyKey(inMap, key))
				{
					template.set(key, inMap.get(key));
				}
				else
				{
					template.setNull(key);
				}
			}
		}

		// リクエスト用クラスの設定
		paramMap.put(JCMConstants.TEMPLATE_LIST_KEY, new CAANMsg[]
		{
			template
		});

		/* ◇ＳＣ呼出実行 */
		// SC呼び出し部品のインスタンス生成（引数にはログに出力するクラス名を渡す。空文字を設定した場合はログに出力されない。
		ServiceComponentRequestInvoker scCall = new ServiceComponentRequestInvoker();
		Map<?, ?> result = scCall.run(paramMap, handle);

		// エラーマッピング処理
		editResultRP(result, param, fixedText);
		// エラーチェック処理
		errChk(result);
		
		CAANMsg[] resultTemplates = (CAANMsg[])result.get(JCMConstants.TEMPLATE_LIST_KEY);
		
		return resultTemplates[0].getCAANMsgList("EKK0321B002CBSMsg1List");
	}

	/**
	 * <pre>
	 * サービスコンポーネント実行後に、IRequestParameterReadWriteに必要なデータをマッピングする
	 * 
	 * </pre>
	 * @param msgList CAANMsgクラス
	 * @param param 業務データ取得・書込用I/F
	 * @param fixedText ユーザ任意文字列
	 * @return 業務データ取得・書込用I/F
	 * @throws Throwable
	 */
	@SuppressWarnings("unchecked")
	private IRequestParameterReadWrite editResultRP(
			Map<?, ?> msgList,
			IRequestParameterReadWrite param,
			String fixedText) 
			throws Throwable 
	{

		// SCからの戻り値からCAANMsgを取得する。
		CAANMsg[] templates = (CAANMsg[])msgList.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg template = templates[0];

		// リターンコード取得
		Integer returnCode = (Integer)msgList.get(JCMConstants.RET_CD_INT_KEY);

		// テンプレートID、ステータス取得
		String templateId = template.getString(JCMConstants.TEMPLATE_ID_KEY);
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		if (returnCode.intValue() != 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 = (HashMap)param.getData(fixedText);

		// ユーザデータ情報にエラー情報をマッピング
		Object[][] contents = null;
		contents = new EKK0011D020CBSMsg().getContents();
		for(int i = 0 ; contents != null && i < contents.length ; i++)
		{
			String element = null;
			element = (String)contents[i][0];
			if (element.indexOf("_err") > 0)
			{
				if (!template.isNull(element))
				{
					if (!inMap.containsKey(element))
					{
						inMap.put(element, template.getString(element));
					}
				}
			}
		}
		
		//エラー情報のマップを取得
		ArrayList<Object> errList = (ArrayList<Object>)param.getControlMapData(SCControlMapKeys.ERROR_INFO);
		if(errList == null)
		{
			errList = new ArrayList<Object>();
		}
		
		// コントロールマップに設定
		param.setControlMapData(SCControlMapKeys.ERROR_INFO, TemplateErrorUtil.getErrorInfo(msgList, errList));

		return param;
	}
	
	/**
	 * エラーチェック処理です。
	 * <br>
	 * @param msgList サービスインタフェース実行結果
	 * @return void
	 * @throws SCCallException 
	 */
	private void errChk(
			Map<?, ?> msgList) 
			throws SCCallException
	{
		CAANMsg[] templates = (CAANMsg[])msgList.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg template = templates[0];

		// リターンコード取得
		Integer returnCode = (Integer)msgList.get(JCMConstants.RET_CD_INT_KEY);
		
		// ステータス取得
		int templateStatus = template.getInt(JCMConstants.STATUS_INT_KEY);
		
		if ((0 != returnCode.intValue()) || (0 != templateStatus))
		{
			String errMsg = "INVALID_RETURN_MESSAGE";
			throw new SCCallException(errMsg, String.valueOf(returnCode), templateStatus);
		}
	}


	/**
	 * 持ちうるフィールドにNullマッピングで埋める
	 * 
	 * @param msg 対象クラス
	 * @param contents 対応クラスのフィールド列挙
	 */
	private void fillCAANMSGNullMapping(CAANMsg msg, Object[][] contents)
	{
		// 要素ごとのループ
		for(int i = 0 ; i < contents.length ; i++)
		{
			Object element = null;
			// キーに該当する箇所の取得
			element = contents[i][0];
			// Nullでマッピング
			msg.setNull((String)element);
		}
	}
	
	/**
	 * @param map
	 * @param key
	 * @return boolean
	 */
	private boolean isEmptyKey(Map<String, Object> map, String key)
	{
		if (map == null || map.get(key) == null || "".equals(map.get(key)))
		{
			return true;
		}
		else
		{
			return false;
		}
	}



}
