/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      	：eo顧客基幹システム
*	モジュール名		：JBSbatCCInsertTFaxSendLog
*	ソースファイル名	：JBSbatCCInsertTFaxSendLog.java
*	作成者				：FJ　
*	作成日				：2011年09月17日
*＜機能概要＞
*　FAX送信履歴ログをテーブル登録します
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/09/17   FJ			新規作成
*********************************************************************/
package  eo.business.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import eo.business.common.JBSbatBusinessService;
import eo.business.common.JCCBatCommon;
import eo.business.util.table.JBSbatCC_T_FAX_SEND_RK_LOG;
import eo.common.util.JCCSendFaxUtil;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.application.JBSbatBusinessException;

/**
* バッチによるFAX送信履歴ログテーブル登録クラスです。 <p>
*<BR>
* @author FJ
*/

public class JBSbatCCInsertTFaxSendLog extends JBSbatBusinessService
{

	/** FAX送信履歴取得開始時間 */
	private static String  FAX_HISTROY_FROM_DTM = "FAX_HISTROY_FROM_DTM";
	
	/** FAX送信履歴開始時間の初回設定取得設定値 */
	private final static String DTM_DEFAULT = "19700101000000000";
	
	/** 仮想FAXグループ名*/
	private static String  FAX_GROUP_NM = "FAX_GROUP_NM";
	
	/** WSDLファイルの配置先パス */
	private static String  FAX_WSDL_PATH = "FAX_WSDL_PATH";
	
	/** dotFAXサービスで使用する名前空間URI */
	private static String  FAX_Q_NM_URI = "FAX_Q_NM_URI";
	
	/** dotFAXサービスで使用する名前空間ローカル部 */
	private static String  FAX_Q_NM_LOCAL = "FAX_Q_NM_LOCAL";

	/** テーブル(FAX送信履歴ログ) */
	private static final String D_TBL_NAME_CC_T_FAX_SEND_RK_LOG = JBSbatCC_T_FAX_SEND_RK_LOG.TABLE_NAME;

	/** SQL定義キー */
	private static final String CC_T_FAX_SEND_RK_LOG_INSERT_001 = "CC_INSERT_001";
	private static final String CC_T_FAX_SEND_RK_LOG_SELECT_001 = "CC_SELECT_001";

	/** テーブルアクセスクラス(ＦＡＸ送信履歴ログ)*/
	private JBSbatSQLAccess db_CC_T_FAX_SEND_RK_LOG = null;

	/** システム時刻(一度取得したら変更しない) */
	private String sysDateTimeStamp = null;
	
	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		
		// DBアクセスクラスを生成します
		db_CC_T_FAX_SEND_RK_LOG = new JBSbatSQLAccess(commonItem, D_TBL_NAME_CC_T_FAX_SEND_RK_LOG);
	}

	/**
	 * 主処理
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute() throws Exception
	{
		//--------------------------------------------------------------------------
		// FAX送信履歴ログ取得パラメータ検査
		//--------------------------------------------------------------------------
		// 仮想FAXグループ名
		String faxGroupNm = JCCBatCommon.getApplicationConst(FAX_GROUP_NM);
		if(chkNull(faxGroupNm))
		{
			throw new JBSbatBusinessException("ECCB0130CE", new String[]{"仮想FAXグループ名(キー：" + FAX_GROUP_NM + ")"});
		}
		
		// WSDLファイルの配置先パス
		String wsdlPath = JCCBatCommon.getApplicationConst(FAX_WSDL_PATH);
		if(chkNull(wsdlPath))
		{
			throw new JBSbatBusinessException("ECCB0130CE", new String[]{"WSDLファイルの配置先(キー：" + FAX_WSDL_PATH + ")"});
		}
		
		// dotFAXサービスで使用する名前空間URI
		String qNmUri = JCCBatCommon.getApplicationConst(FAX_Q_NM_URI);
		if(chkNull(qNmUri))
		{
			throw new JBSbatBusinessException("ECCB0130CE", new String[]{"dotFAXサービスで使用する名前空間URI(キー：" + FAX_Q_NM_URI + ")"});
		}
		
		// dotFAXサービスで使用する名前空間ローカル部
		String qNmLocal = JCCBatCommon.getApplicationConst(FAX_Q_NM_LOCAL);
		if(chkNull(qNmLocal))
		{
			throw new JBSbatBusinessException("ECCB0130CE", new String[]{"dotFAXサービスで使用する名前空間ローカル部(キー：" + FAX_Q_NM_LOCAL + ")"});
		}
		
		// 現在のシステム時刻を取得（一度取得したら変更しない）
		sysDateTimeStamp = JCCBatCommon.getSysDateTimeStamp();
		
		// 仮想FAXグループ名は";"区切りでセパレートする
		String[] faxGroupNmList = faxGroupNm.split(";");
		
		// dotFAXとの連携に必要なパラメータをマッピング
		HashMap<String, Object> inputMap = new HashMap<String, Object>();
		inputMap.put(FAX_WSDL_PATH, wsdlPath);							// wsdlパス
		inputMap.put(FAX_Q_NM_URI, qNmUri);								// 名前空間URI
		inputMap.put(FAX_Q_NM_LOCAL, qNmLocal);							// 名前空間ローカル部
		
		// 送信履歴を仮想FAXグループの数分取得する
		for(int i = 0; i < faxGroupNmList.length; i++)
		{
			// FAX送信履歴ログの登録是非判定用ArrayList
			ArrayList<String> chkInsertArray = new ArrayList<String>();
			
			// 仮想FAXグループ名の指定
			inputMap.put(FAX_GROUP_NM, faxGroupNmList[i]);
			
			// FAX送信履歴ログテーブルから最新の送信終了日時を取得(次取得日時の起点とする)
			// また、FAX送信履歴ログの登録是非判定用リストにFAX送信番号を登録する
			inputMap.put(FAX_HISTROY_FROM_DTM, executeCC_T_FAX_SEND_RK_LOG_CC_SELECT_001(faxGroupNmList[i], chkInsertArray));
			
			// FAX送信履歴の取得
			ArrayList<HashMap<String, Object>> faxSendHistoryList = JCCSendFaxUtil.getSendHistory(inputMap);
			
			// 送信履歴が1件も存在しない場合は、テーブル登録しない
			if(null == faxSendHistoryList || faxSendHistoryList.size() == 0)
			{
				super.logPrint.printDebugLog("HistoryCnt:" + faxGroupNmList[i] + "=0");
				continue;
			}
			
			super.logPrint.printDebugLog("HistoryCnt:" + faxGroupNmList[i] + "=" + String.valueOf(faxSendHistoryList.size()));
			
			// FAX送信履歴をテーブル登録する
			for(int j = 0; j < faxSendHistoryList.size(); j++)
			{
				insertFaxSendLog(faxSendHistoryList.get(j), chkInsertArray);
			}
		}
		
		return null;
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
		// DBアクセスクラスをクローズします
		db_CC_T_FAX_SEND_RK_LOG.close();
	}

	/**
	 * FAX送信履歴情報をDB登録する
	 * <br>
	 * @param historyMap FAX送信履歴情報Map
	 * @param chkInsertMap FAX送信履歴情報登録是非判定用リスト
	 * @throws Exception
	 */
	private void insertFaxSendLog(HashMap<String, Object> historyMap, ArrayList<String> chkInsertArray) throws Exception
	{
		ArrayList<String> historyParam = new ArrayList<String>();
		
		// 指定のFAX送信番号が既にテーブルに登録済の場合は何もせずに復帰
		String faxSendNo = historyMap.get("FAX_SEND_NUM").toString();
		if(chkInsertArray.contains(faxSendNo) == true)
		{
			return;
		}
		// FAX送信番号
		historyParam.add(faxSendNo.substring(0, 14));
		
		// FAX送信履歴ログ番号
		historyParam.add(faxSendNo.substring(14, 17));
		
		// 世代登録年月日時分秒
		historyParam.add(this.sysDateTimeStamp);
		
		// 送信依頼元IPアドレス
		historyParam.add(historyMap.get("FAX_REQ_HOST_NM").toString());
		
		// 送信依頼受付年月日時分秒
		historyParam.add(historyMap.get("FAX_REQ_DTM").toString());
		
		// 送信終了年月日時分秒
		HashMap<String, Object> faxSendResulrIf = (HashMap<String, Object>)historyMap.get("FAX_SEND_RESULT_IF");
		
		if(faxSendResulrIf.get("SendEndDateTime") != null)
		{
			historyParam.add(faxSendResulrIf.get("SendEndDateTime").toString());
		}
		else
		{
			historyParam.add("19700101000000000");
		}
		
		// 送信対象名
		historyParam.add(historyMap.get("FAX_TARGET_NM").toString());
		
		// 電話番号
		historyParam.add(historyMap.get("FAX_TEL_NUM").toString());
		
		// イメージファイル名
		historyParam.add(historyMap.get("FAX_FILE_NM").toString());
		
		// ユーザーデータ
		historyParam.add(historyMap.get("FAX_USER_DATA").toString());

		// 送信オプション情報
		historyParam.add(mapToString((HashMap<String, Object>)historyMap.get("FAX_SEND_OPT_IF")));
		
		// 送信状態コード
		historyParam.add(faxSendResulrIf.get("Status").toString());
		
		// エラー理由コード
		historyParam.add(faxSendResulrIf.get("ErrorReason").toString());
		
		// 送信結果詳細コード
		if("0".equals(faxSendResulrIf.get("ErrorReason").toString()))
		{
			historyParam.add("0000");
		}
		else
		{
			if(faxSendResulrIf.get("ResultCode") != null)
			{
				historyParam.add(faxSendResulrIf.get("ResultCode").toString());
			}
			else
			{
				historyParam.add("9999");
			}
		}
		
		// 送信状態詳細情報
		historyParam.add(mapToString(faxSendResulrIf));
		
		// 登録年月日時分秒
		historyParam.add(this.sysDateTimeStamp);
		
		// 登録オペレータアカウント
		historyParam.add(super.commonItem.getBatchUserId());
		
		// 更新年月日時分秒
		historyParam.add(this.sysDateTimeStamp);
		
		// 更新オペレータアカウント
		historyParam.add(super.commonItem.getBatchUserId());
		
		// 削除年月日時分秒
		historyParam.add(null);
		
		// 削除オペレータアカウント
		historyParam.add(null);
		
		//  無効フラグ
		historyParam.add("0");
		
		executeCC_T_FAX_SEND_RK_LOG_CC_INSERT_001((String[])historyParam.toArray(new String[0]));
		
	}
	
	/**
	 * 指定されたバインド変数を元に、FAX送信履歴ログ情報をテーブル登録します
	 * 
	 * @param param バイント変数の値配列
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private void executeCC_T_FAX_SEND_RK_LOG_CC_INSERT_001(String[] param) throws Exception
	{
		// バイント変数のリストの生成
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		
		for(int i = 0; i < param.length; i++)
		{
			paramList.setValue(param[i]);
		}
		
		//SQL実行
		db_CC_T_FAX_SEND_RK_LOG.executeBySqlDefine(paramList, CC_T_FAX_SEND_RK_LOG_INSERT_001);
	}
	
	/**
	 * 指定されたバインド変数を元に、FAX送信履歴ログ情報をテーブルから取得します
	 * また、FAX送信番号と送信履歴ログ番号をリストに格納します
	 * 
	 * @param param バイント変数
	 * @param chkInsertArray FAX送信番号と送信履歴ログ番号を組み合わせて格納するリスト
	 * @return 最新のFAX送信受付日時
	 * @throws Exception 業務サービス内で発生した例外全般。
	 */
	private String executeCC_T_FAX_SEND_RK_LOG_CC_SELECT_001(String param, ArrayList<String> chkInsertArray) throws Exception
	{
		// 送信受付日時
		String sendReqUkDtm = null;
		
		// 結果格納用領域
		JBSbatCommonDBInterface rsMap = null;
		
		// バイント変数のリストの生成
		JBSbatCommonDBInterface paramList = new JBSbatCommonDBInterface();
		paramList.setValue(param);
		
		// SQL実行
		db_CC_T_FAX_SEND_RK_LOG.selectBySqlDefine(paramList, CC_T_FAX_SEND_RK_LOG_SELECT_001);
		
		// 最新のFAX送信受付日時を取得
		while((rsMap = db_CC_T_FAX_SEND_RK_LOG.selectNext()) != null)
		{
			// FAX送信受付日時の取得
			sendReqUkDtm = rsMap.getString(JBSbatCC_T_FAX_SEND_RK_LOG.SEND_REQ_UK_DTM);
			
			// FAX送信番号と送信履歴ログ番号を組み合わせてFAX送信番号をリストで管理
			String faxSendNo = rsMap.getString(JBSbatCC_T_FAX_SEND_RK_LOG.FAX_SEND_NO);
			String faxSendRkLogNo = rsMap.getString(JBSbatCC_T_FAX_SEND_RK_LOG.FAX_SEND_RK_LOG_NO);
			chkInsertArray.add(faxSendNo + faxSendRkLogNo);
		}
		if(chkNull(sendReqUkDtm))
		{
			return DTM_DEFAULT;
		}
		return sendReqUkDtm;
	}
	
	/**
	 * HashMap形式の情報をStringに変換する
	 * 
	 * @param sendOptionMap 送信オプション情報HashMap
	 * @return String形式に変換した送信オプション情報
	 * @throws Exception
	 */
	private String mapToString(HashMap<String, Object> sendOptionMap) throws Exception
	{
		if(sendOptionMap == null || sendOptionMap.size() == 0){
			
			return null;
		}
		
		StringBuffer buf = new StringBuffer();
		String lineFeed = System.getProperty("line.separator");
		
		// 登録されているキーと値を[キー][=][値][改行コード]区切りで登録
		String key = null;
		String value = null;
		
		Set keySet = sendOptionMap.keySet();
		Iterator keyIte = keySet.iterator();
		while(keyIte.hasNext())
		{
			// 登録されたキーの取得
			key = (String)keyIte.next();
			
			// FAXヘッダー情報はリスト形式のため連番付きで連結
			// 現状はFaxHeaderInfoは送られてこないため、コメント化
			if("FaxHeaderInfo".equals(key))
			{
//				ArrayList<HashMap<String, Object>> faxHeadInfoArray = (ArrayList<HashMap<String, Object>>)sendOptionMap.get("FaxHeaderInfo");
//				for(int i = 0; i < faxHeadInfoArray.size(); i++)
//				{
//					String seq = String.format("%03d", i);
//					
//					buf.append(key + seq + "=");
//					
//					// FAXヘッダー情報は[キー][;][値][,]区切りで登録
//					HashMap<String, Object> headMap = faxHeadInfoArray.get(i);
//					Set headKeySet = headMap.keySet();
//					Iterator headKeyIte = keySet.iterator();
//					String headKey = null;
//					String headValue = null;
//					
//					while(headKeyIte.hasNext())
//					{
//						headKey = (String)headKeyIte.next();
//						headValue = (String)headMap.get(headKey);
//						buf.append(headKey + ";" + headValue + ",");
//					}
//					
//					buf.append(lineFeed);
//				}
			}
			// それ以外のキーで取得する値はそのまま連結
			else
			{
				value = (String)sendOptionMap.get(key);
				buf.append(key + "=" + value + lineFeed);
			}
		}
		return buf.toString();
	}
	
	/**
	 * オブジェクトに値が設定されているか判定する
	 * <br>
	 * @param arg0 判定する文字列
	 * @return オブジェクトに値が設定されていない場合はtrue
	 */
	private static boolean chkNull(Object arg0) 
	{
		if (null == arg0) 
		{
			return true;
		}
		if(arg0 instanceof String)
		{
			if(arg0.toString().length() == 0)
			{
				return true;
			}
		}
		else if(arg0 instanceof String[])
		{
			String[] arg1 = (String[])arg0;
			if(arg1.length == 0)
			{
				return true;
			}
		}
		return false;
	}

}
