/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：ApiBpInterface
*   ソースファイル名：ApiBpInterface.java
*   作成者          ：富士通
*   日付            ：2018年07月13日
*＜機能概要＞
*   Bp層のサービス処理連携部品クラスです。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2018/07/13   FJ)鈴木     新規作成【ANK-3452-00-00_標準APIを利用した他システム連携基盤の構築】
*   v39.00.00   2018/11/27   FJ)鈴木     【ANK-3477-00-00】eoマイページからのお客さま情報変更自動反映
*   v41.00.00   2019/01/30   FJ)中原     【ANK-3355-00-00】LINEへの契約情報連携
**********************************************************************/
package local.gyomu.api.common;

import java.util.HashMap;
import java.util.Map;

import local.gyomu.api.exception.ApiSystemException;

import com.fujitsu.futurity.bp.controller.client.ControllerClient;
import com.fujitsu.futurity.bp.controller.client.DefaultTelegramIDGenerator;
import com.fujitsu.futurity.bp.controller.client.RequestTelegram;
import com.fujitsu.futurity.bp.controller.client.ResponseTelegram;
import com.fujitsu.futurity.bp.controller.client.exception.BPMControllerException;
import com.fujitsu.futurity.common.x01.sc.SCControlMapKeys;

public class ApiBpInterface {

	/** ユースケースID */
	public static final String TELEGRAM_INFO_USECASE_ID = "ユースケースID";
	/** オペレーションID */
	public static final String TELEGRAM_INFO_OPERATION_ID = "オペレーションID";
	/** 運用日時 */
	public static final String TELEGRAM_INFO_OPERATE_DATETIME = "運用日時";
	/** オペレータID */
	public static final String TELEGRAM_INFO_OPERATOR_ID = "オペレータID";
	
	/** リターンコード */
	public static final String RETURN_CODE = "RETURN_CODE";
	/** リターンメッセージ */
	public static final String RETURN_MESSAGE = "RETURN_MESSAGE";
	/** エラー情報 */
	public static final String ERROR_INFO = "ERROR_INFO";
	// ANK-3355-00-00 ADD START
	/** ボディ情報 */
	public static final String BODY_INFO = "BODY_INFO";
	// ANK-3355-00-00 ADD END
	
	/** リターンコード(正常) */
	public static final String RETURN_CODE_SUCCESS = "0000";
//	/** リターンコード(警告) */
//	public static final String RETURN_CODE_WARNING = "0004";
//	/** リターンコード(単項目チェックエラー) */
//	public static final String RETURN_CODE_SINGLEDATA_ERR = "1000";
//	/** リターンコード(単関連チェックエラー) */
//	public static final String RETURN_CODE_ITEM_RELATION_ERR = "1050";
//	/** リターンコード(関連チェックエラー) */
//	public static final String RETURN_CODE_RELATION_ERR = "1100";
//	/** リターンコード(状態遷移チェックエラー) */
//	public static final String RETURN_CODE_STATUSTRANS_ERR = "1150";
//	/** リターンコード(サービスを呼び出す権限無し) */
//	public static final String RETURN_CODE_AUTHORITY_ERR = "5000";
//	/** リターンコード(全機能の参照/更新業務規制状態エラー) */
//	public static final String RETURN_CODE_SELECT_UPDATE_AUTHORITY_ERR = "8000";
//	/** リターンコード(全機能の更新業務規制状態エラー) */
//	public static final String RETURN_CODE_UPDATE_AUTHORITY_ERR = "8010";
	/** リターンコード(システムエラー) */
	public static final String RETURN_CODE_SYSTEMERR = "9000";
	
	/** 依頼元システム区分  "3":外部システム連携(固定値) */
	public static final String REQ_CHANNEL_3 = "3";
	
	/** サービス呼び出し区分 */
	public static final String SERVICE_CALL_TYPE_3 = "3";
	
	/** オペレータID */
	public static final String OPERATOR_ID = "TRK1";

	/**
	 * サービスを呼び出します。
	 * （koptBatchの同じクラスを参考にしました）
	 * 
	 * @param commonItem 業務共通電文クラスオブジェクト
	 * @param paramMap ユースケースIDを格納したマップ
	 * @param inputMap サービスに渡す業務データを格納したマップ
	 * @param outputMap サービスの処理結果を受け取る空のマップ
	 * @throws ApiSystemException 
	 */
	public static void invokeService( ApiCommonItem commonItem, HashMap paramMap, HashMap inputMap, HashMap outputMap ) throws ApiSystemException {
		// 入力パラメータのNULLチェック
		checkParameterMap(commonItem, paramMap, inputMap, outputMap);

		// リクエスト電文生成
		RequestTelegram requestTelegram = new RequestTelegram();
		
		// ユースケースIDを設定
		requestTelegram.setUsecaseID((String)paramMap.get(TELEGRAM_INFO_USECASE_ID));
		// 運用日時(yyyymmddhhMMssSSS)
		String operateDateTime = null;
		// 運用日時 nullを設定
		requestTelegram.setOpeTime(operateDateTime);
		
		// チャネル(依頼元システム区分)(新SOAPと同じように "3":外部システム連携 を設定)
		requestTelegram.setChannel(REQ_CHANNEL_3);
		
		// コントロールマップの生成 
		HashMap<Object, Object>  ctrlMap = new HashMap<Object, Object>();
		ctrlMap.put(SCControlMapKeys.REQ_VIEWID, commonItem.getJobid()); // VIEWID:バッチのJOBIDを設定する。
// ANK-3477-00-00 2018.12.05 mod start
//		ctrlMap.put(SCControlMapKeys.OPERATOR_ID, OPERATOR_ID);
		String operatorId = commonItem.getOperatorId();
		if (operatorId == null || "".equals(operatorId)) {
			operatorId = OPERATOR_ID;
		}
		ctrlMap.put(SCControlMapKeys.OPERATOR_ID, operatorId);
// ANK-3477-00-00 2018.12.05 mod end
		
		// 運用日付、時刻は未設定
//		ctrlMap.put(SCControlMapKeys.OPE_DATE, commonItem.getOpeDate()); 			// 運用日付をセット
//		ctrlMap.put(SCControlMapKeys.OPE_TIME, "20180621134000111"); // システム日時をセット

		// ユーザエリアにユーザデータマップ、コントロールマップを設定
		requestTelegram.setControlMapData(ctrlMap);
		requestTelegram.setUserData(inputMap);
		
		// サービス呼び出しタイプを設定(新SOAPと同じように"3"を設定)
		requestTelegram.setCallType(SERVICE_CALL_TYPE_3);
		
		// 電文ID（リクエストID）を採番し設定
		DefaultTelegramIDGenerator dtig = new DefaultTelegramIDGenerator();
		String telegramId = dtig.createTelegramID();
		requestTelegram.setTelegramID(telegramId);
		
		// 連携FW呼び出し実行
		ControllerClient controllerClient = null;
		try {
			controllerClient = new ControllerClient();
		} catch (BPMControllerException e) {
			// エラー
			ApiSystemException jcce = new ApiSystemException();
			jcce.initCause(e);
			throw jcce;
		}
		
		// SOAPの戻り値
		ResponseTelegram responseTelegram = null;
		try {
			responseTelegram = controllerClient.execute(requestTelegram);
		} catch (BPMControllerException e) {
			ApiSystemException jcce = new ApiSystemException();
			jcce.initCause(e);
			throw jcce;
		}
		
		// 戻りのユーザエリアデータ取得
		Map<Object, Object> resultDataMap = responseTelegram.getUserData();

		// リターンコードを取得
		String returnCode = responseTelegram.getReturnCode();
		// リターンメッセージを取得
		String returnMessage = responseTelegram.getReturnMessage();
		// エラー情報を取得
		Object errInfo = responseTelegram.getErrorInfo();

		// リターンコードを取得できない場合、処理を継続する事ができない為、例外をスローする。
		if ( returnCode == null || returnCode.length() == 0 ) {
			throw new ApiSystemException("リターンコードが取得できません。");
		}

//		// 2012/12/25 FST_mukuo)業務エラー情報を業務ログに出力する(システムエラー時は業務ログには出力しない) start
//		if(!RETURN_CODE_SUCCESS.equals(returnCode) && !RETURN_CODE_SYSTEMERR.equals(returnCode))
//		{
//			if(null != errInfo)
//			{
//				// コメントアウト
//				commonItem.getLogPrint().printLogMsg(JBSbatBusinessBase.BUSINESS_ERROR_RECORD, errInfo.toString());
//			}
//		}
		
		// システムエラー(9000)
		if(RETURN_CODE_SYSTEMERR.equals(returnCode)){
			// システムエラーの場合、例外をスローする。
			throw new ApiSystemException("サービス層でシステムエラーが発生しました。サービス層のログを確認して下さい。電文ID【" + telegramId + "】");
			
		} else{
			// 正常終了、業務エラーの場合はoutputMapに情報を全て詰め込む。
			outputMap.putAll(resultDataMap);
			// リターンコードをoutputMapに設定する。
			outputMap.put(RETURN_CODE, returnCode);
			// リターンメッセージをoutputMapに設定する。
			outputMap.put("RETURN_MESSAGE", returnMessage);
			// エラー情報をoutputMapに設定する。
			outputMap.put(ERROR_INFO, errInfo);
		}
	}
	
	/**
	 * 
	 * サービスの処理結果を格納したマップからリターンコードを取得します。
	 * 
	 * @param outputMap サービスの処理結果を格納したマップ
	 * @return リターンコード
	 */
	public static String getReturnCode( Map outputMap ) {
		if ( outputMap == null ) {
			return null;
		}
		return (String) outputMap.get(RETURN_CODE);
	}

	/**
	 * 
	 * サービスの処理結果を格納したマップからリターンメッセージを取得します。
	 * 
	 * @param outputMap サービスの処理結果を格納したマップ
	 * @return リターンメッセージ
	 */
	public static String getReturnMessage( Map outputMap ) {
		if ( outputMap == null ) {
			return null;
		}
		return (String) outputMap.get(RETURN_MESSAGE);
	}

	/**
	 * 
	 * サービスの処理結果を格納したマップからエラー情報を取得します。
	 * 
	 * @param outputMap サービスの処理結果を格納したマップ
	 * @return エラー情報
	 */
	public static Object getErrorInfo( Map outputMap ) {
		if ( outputMap == null ) {
			return null;
		}
		return (String) outputMap.get(ERROR_INFO);
	}

	/**
	 * 
	 * 指定された日付(yyyymmdd)に、システム日時の時間(hhMMssSSS)を結合した日時を返却します。
	 * 
	 * @param operationDate 運用日付
	 * @return 運用日時
	 */
	private static String getOperationDateTime( String operationDate ) {
		
		// 常にnullを返却する
		return null;
		
	}
	
	/**
	 * 
	 * invokeServiceの入力パラメータのNULLチェックを行います。<BR>
	 * チェックに該当した場合、該当したオブジェクトの情報を例外のメッセージとして<BR>
	 * JCCbatFrameworkExceptionをスローします。<BR>
	 * 
	 * @param commonItem 業務共通電文オブジェクト
	 * @param paramMap ユースケースID格納マップ
	 * @param inputMap 業務データマップ
	 * @param outputMap サービス処理結果マップ
	 * @throws ApiSystemException 
	 */
	private static void checkParameterMap( ApiCommonItem commonItem, HashMap paramMap, HashMap inputMap, HashMap outputMap ) throws ApiSystemException {
		// エラー検知フラグ
		boolean isError = false;
		
		// エラーメッセージ格納バッファ
		StringBuffer buf = new StringBuffer();
		buf.append("at eo.framework.util.JCCBatchEsbInterface.invokeService： 入力パラメータが不正です。");
		
		// 業務共通電文オブジェクトがNULL
		if ( commonItem == null ) {
			isError = true;
			buf.append("業務共通電文オブジェクト ");
		}
		// ユースケースID格納マップがNULL
		if ( paramMap == null ) {
			isError = true;
			buf.append("ユースケースID格納マップ ");
		}
		// 業務データマップがNULL
		if ( inputMap == null ) {
			isError = true;
			buf.append("業務データマップ ");
		}
		// サービス処理結果マップがNULL
		if ( outputMap == null ) {
			isError = true;
			buf.append("サービス処理結果マップ");
		}
		
		// エラーがある場合例外をスローする
		if ( isError ) {
			throw new ApiSystemException( buf.toString() );
		}
	}
	
}
