/*********************************************************************
 * All Rights reserved,Copyright (c) K-Opticom, 2011
 **********************************************************************
 *＜プログラム内容＞
 *   システム名      ：eo顧客基幹システム
 *   モジュール名    ：JKKPplanChangeCC
 *   ソースファイル名：JKKPplanChangeCC.java
 *   作成者          ：富士通
 *   日付            ：2012年09月04日
 *＜機能概要＞
 *   料金プラン切替部品
 *＜修正履歴＞
 *   バージョン  修正日       修正者      修正内容
 *   v4.00.00    2012/09/04   FJ）藤川    新規作成
 *
 **********************************************************************/
package com.fujitsu.futurity.bp.custom.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.fujitsu.futurity.bp.custom.constant.JKKPplanChangeConstCC;
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.IRequestParameterReadOnly;
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.EKK0591B004CBSMsg;
import eo.ejb.cbs.cbsmsg.EKK0591B004CBSMsg1List;

@SuppressWarnings({"unchecked"})
public class JKKPplanChangeCC extends AbstractCommonComponent {

	//*********************************************
	//                ユーザ定義
	//*********************************************
	/** エラーメッセージ */
	private static final String ERR_MSG = "INVALID_RETURN_MESSAGE";
	
	//*********************************************
	//                サービスIF
	//*********************************************
	
	/** 料金グループコード別料金プラン一覧照会 */
	private static final String EKK0591B004 = "EKK0591B004";
	
	//******************************************
	//             機能コード
	//******************************************
	/** 機能コード；１ */
	private static final String FUNC_CD_1 = "1";
	
	//******************************************
	//             ユーザ定義文字列
	//******************************************
	// IT1-2013-0000291 2013/02/26 MOD START
//	private static String fixText = null;
	private String fixText = null;
	// IT1-2013-0000291 2013/02/26 MOD END
	
	/** 料金種別コード １：サービス契約 */
	private static final String PCRS_SBT_CD_1 = "1";
	
	/**
	 * 料金プラン切替
	 * @param handle セッションハンドル
	 * @param param リクエストパラメータ
	 * @param fixedText サービスメッセージ
	 * @return リクエストパラメータ
	 * @throws Throwable 例外時にスローします
	 */
	public IRequestParameterReadWrite pplanChange(SessionHandle handle, IRequestParameterReadWrite param, String fixedText)
			throws Throwable
	{
		
		fixText = fixedText;
		HashMap<String, Object> work;
		HashMap<String, Object> resultHash= new HashMap<String, Object>();
		
		Map<String, Object> userData = (HashMap<String, Object>)param.getData(fixText);
		// 引継ぎ情報取得
		work = getHktgData(userData);
		
		// 料金グループコード別料金プラン一覧照会
		callEKK0591B004SC(param, handle, work, resultHash, fixedText);
		
		editPplan(userData, resultHash);
		
		// 処理終了
		return param;
	}
	
	/**
	 * 引継ぎデータ取得
	 * @param userData
	 * @return
	 */
	private HashMap<String, Object> getHktgData(Map<String, Object> userData)
	{
		HashMap<String, Object> work = new HashMap<String, Object>();
		
		// 料金グループコード
		work.put(JKKPplanChangeConstCC.PRC_GRP_CD, (String)userData.get(JKKPplanChangeConstCC.PRC_GRP_CD));
		
		return work;
	}
	
	/**
	 * 取得結果より返却用に編集
	 * @param userData
	 * @param resultHash
	 */
	private void editPplan(Map<String, Object> userData, HashMap<String, Object> resultHash)
	{
		List<HashMap<String, Object>> pplanList = new ArrayList<HashMap<String, Object>>();
		
		// 料金グループコード別料金プラン一覧照会結果
		CAANMsg[] eKK0591B004CBSMSG1list = (CAANMsg[])resultHash.get(EKK0591B004CBSMsg.EKK0591B004CBSMSG1LIST);
		
		if (eKK0591B004CBSMSG1list != null && eKK0591B004CBSMSG1list.length > 0)
		{
			for(int i=0; i < eKK0591B004CBSMSG1list.length; i++)
			{
				HashMap<String, Object> eKK0591B004CBSMSG1 = eKK0591B004CBSMSG1list[i].getMsgData();
				HashMap<String, Object> pplanMap = new HashMap<String, Object>();
				// 料金グループコード
				pplanMap.put("prc_grp_cd", (String)eKK0591B004CBSMSG1.get(EKK0591B004CBSMsg1List.PRC_GRP_CD));
				
				// 料金コースコード
				pplanMap.put("pcrs_cd", (String)eKK0591B004CBSMSG1.get(EKK0591B004CBSMsg1List.PCRS_CD));
				
				// 料金コース名
				pplanMap.put("pcrs_nm", (String)eKK0591B004CBSMSG1.get(EKK0591B004CBSMsg1List.PCRS_NM));
				
				// 料金プランコード
				pplanMap.put("pplan_cd", (String)eKK0591B004CBSMSG1.get(EKK0591B004CBSMsg1List.PPLAN_CD));
				
				// 料金プラン名
				pplanMap.put("pplan_nm", (String)eKK0591B004CBSMSG1.get(EKK0591B004CBSMsg1List.PPLAN_NM));
				
				pplanList.add(pplanMap);
			}
		}
		userData.put("pplan_list", pplanList);
	}
	
	/**
	 * 料金グループコード別料金プラン一覧照会
	 * @param param
	 * @param handle
	 * @param paramMap
	 * @param resultHash
	 * @return
	 * @throws Throwable
	 */
	private int callEKK0591B004SC(IRequestParameterReadWrite param, SessionHandle handle, HashMap<String, Object> work,
			HashMap<String, Object> resultHash, String fixedText) throws Throwable
	{
		HashMap<String, Object> sIFRequest = null;
		CAANMsg template = null;
		ServiceComponentRequestInvoker scCall = null;
		Map<?, ?> sIFResult = null;
		int status = 0;

		// サービスIF共通の情報を設定
		sIFRequest = editInMsgCmn(param);

		// EKK0591B004への呼び出しパラメータ設定
		template = new CAANMsg(EKK0591B004CBSMsg.class.getName());
		mappingEKK0591B004InMsg(template, work);
		editBasicCmn(param, template);

		// リクエスト用クラスの設定
		sIFRequest.put(JCMConstants.TEMPLATE_LIST_KEY, new CAANMsg[]
		{
			template
		});

		// SC呼び出しクラスの生成
		scCall = new ServiceComponentRequestInvoker();

		// SIFの呼び出し
		sIFResult = scCall.run(sIFRequest, handle);
		// エラーマッピング
		editResultRP(sIFResult, param);
		// エラーチェック処理
		errChk(sIFResult);

		// SIFの実行結果を設定
		resultHash.putAll(getWorkCAANMsg(sIFResult));

		// ステータスコードの取得
		status = template.getInt(JCMConstants.STATUS_INT_KEY);

		return status;

	}
	
	/**
	 * templateに対してEKK0591B004の条件に関する部分を設定する
	 * 
	 * @param template
	 * @param inHash
	 */
	private void mappingEKK0591B004InMsg(CAANMsg template, HashMap<String, Object> work)
	{
		// 全条件のNullマッピング
		fillCAANMSGNullMapping(template, new EKK0591B004CBSMsg().getContents());

		// テンプレートID(SIFのID)
		template.set(EKK0591B004CBSMsg.TEMPLATEID, EKK0591B004);

		// 機能コード--料金グループコード別料金プラン一覧照会
		template.set(EKK0591B004CBSMsg.FUNC_CODE, FUNC_CD_1);

		// ＫＥＹ＿料金グループコード
		template.set(EKK0591B004CBSMsg.KEY_PRC_GRP_CD, (String)work.get(JKKPplanChangeConstCC.PRC_GRP_CD));

		// ＫＥＹ＿料金コース種別コード（1：サービス契約）
		template.set(EKK0591B004CBSMsg.KEY_PCRS_SBT_CD, PCRS_SBT_CD_1);
	}
	
	/**
	 * チェック処理<br>
	 * サービスコンポーネント実行用CAANMsgを返却します。<br>
	 * <br>
	 * 
	 * @param handle セッションハンドル
	 * @param param (I) 業務データ取得用I/F
	 * @param fixedText (I) ユーザ定義文字列
	 * @return サービスコンポーネント実行用CAANMsg
	 * @exception Throwableがスローされます 。
	 */
	public HashMap<String, Object> getInvokeCBS(SessionHandle handle, IRequestParameterReadWrite param, String fixedText) throws Throwable
	{
		HashMap<String, Object> map = new HashMap<String, Object>();
		// SCインプット共通データ
		// **********************************************
		// 【取得元：電文ヘッダ(ヘッダ)】
		// **********************************************
		// 電文ID
		map.put(JCMConstants.TRANZACTION_ID_KEY, param.getTelegramID());
		// ユースケースID
		map.put(JCMConstants.USECASE_ID_KEY, param.getUsecaseID());
		// オペレーションID
		map.put(JCMConstants.OPERATION_ID_KEY, param.getOperationID());
		// サービス呼び出し区分
		map.put(JCMConstants.CALL_TYPE_KEY, param.getCallType());

		// **********************************************
		// 【取得元：ユーザエリア(コントロールマップ)】
		// **********************************************
		// 依頼先ホスト名
		map.put(JCMConstants.CLIENT_HOST_NAME_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTNAME));
		// 依頼元IPアドレス
		map.put(JCMConstants.CLIENT_IP_ADDRESS_KEY, param.getControlMapData(SCControlMapKeys.REQ_HOSTIP));
		// 依頼元画面ID
		map.put(JCMConstants.INVOKE_GAMEN_ID_KEY, param.getControlMapData(SCControlMapKeys.REQ_VIEWID));
		// オペレータID
		map.put(JCMConstants.OPERATOR_ID_KEY, param.getControlMapData(SCControlMapKeys.OPERATOR_ID));

		map.put(JCMConstants.TEMPLATE_LIST_KEY, null);

		return map;
	}
	
	/**
	 * サービスインターフェイス処理結果(エラー情報)の取得<br>
	 * 業務データ取得・書込用I/Fをそのまま返却します。<br>
	 * <br>
	 * @param param デルグループ、コントロールマップを含むパラメータオブジェクト
	 * @param templates CAANMsgクラス配列
	 * @param returnCode リターンコード
	 * @return 業務データ取得・書込用I/F
	 * @throws Throwable
	 */
	public IRequestParameterReadWrite editErrorInfo(IRequestParameterReadWrite param,
			CAANMsg[] templates, int returnCode) throws Throwable
	{
		return param;
	}
	
	/**
	 * 業務データの取得処理です。
	 * 
	 * @param rslt SVIFの実行結果データ
	 * @return 業務データ
	 */
	private HashMap<String, Object> getWorkCAANMsg(Map<?, ?> rslt)
	{
		CAANMsg[] templates = (CAANMsg[])rslt.get(JCMConstants.TEMPLATE_LIST_KEY);
		CAANMsg parentTemplate = templates[0];

		return parentTemplate.getMsgData();
	}
	
	/**
	 * 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 param リクエストパラメータ
	 * @param template template 条件の設定先
	 * @throws RequestParameterException
	 */
	private void editBasicCmn(IRequestParameterReadOnly param, CAANMsg template)
	throws RequestParameterException
	{
		
		// オペレータ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);
		
	}
	
	/**
	 * サービスI/F実行用の共通部を設定します<br>
	 * <br>
	 * 
	 * @param param (I) 業務データ取得用I/F
	 * @param msg データ登録内容
	 * @return オプションサービス契約作成数
	 * @throws RequestParameterException
	 * @exception RequestParameterExceptionがスローされます 。
	 */
	private HashMap<String, Object> editInMsgCmn(IRequestParameterReadOnly param) 
	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));
				
		return paramMap;
		
	}
	
	/**
	 * エラーチェック処理です。 <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 = ERR_MSG;
			throw new SCCallException(errMsg, String.valueOf(returnCode), templateStatus);
		}
	}
	
	/**
	 * <pre>
	 * サービスコンポーネント実行後に、IRequestParameterReadWriteに必要なデータをマッピングする
	 * 
	 * @param msgList CAANMsgクラス
	 * @param param 業務データ取得・書込用I/F
	 * @param fixedText ユーザ任意文字列
	 * @return 業務データ取得・書込用I/F
	 * @throws Throwable
	 */
	private IRequestParameterReadWrite editResultRP(Map<?, ?> msgList, IRequestParameterReadWrite param)
			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(fixText);
		
		// ユーザデータ情報にエラー情報をマッピング
		Object[][] contents = null;
		if (EKK0591B004.equals(templateId))
		{
			contents = new EKK0591B004CBSMsg().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;
	}
}
