/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*	モジュール名	：JBSBatKKShoriIraiUtil
*	ソースファイル名：JBSBatKKShoriIraiUtil.java
*	作成者			：富士通
*	日付			：2013年10月21日
*＜機能概要＞
*	ディレイド処理依頼の確認、および、結果登録を行います。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v5.00.00	2013/10/21	富士通		新規作成
*
**********************************************************************/

package eo.business.common;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import eo.common.util.JCCFileUtil;
import eo.framework.application.JCCbatFrameworkException;
import eo.framework.db.JBSbatDBConnection;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.util.JBSbatCheckUtil;


/**
 * ディレイド処理依頼の確認、および、結果登録を行います。getKariFileData
 * <br>
 * @author 富士通
 */
public class JBSBatKKShoriIraiUtil {

	/** ディレイド処理依頼番号 */
	private static final String	DLYD_TRN_REQ_NO = "DLYD_TRN_REQ_NO";
	
	/** ディレイド処理依頼ステータス */
	private static final String	DLYD_TRN_REQ_STAT = "DLYD_TRN_REQ_STAT";

	/** 入力電子ファイル管理番号 */
	private static final String	INPUT_EFILE_KANRI_NO = "INPUT_EFILE_KANRI_NO";
	
	/** 入力電子ファイル世代登録年月日時分秒 */
	private static final String	INPUT_EFILE_GENE_ADD_DTM = "INPUT_EFILE_GENE_ADD_DTM";
	
	/** 依頼ジョブID */
	private static final String	REQ_JOB_ID = "REQ_JOB_ID";
	
	/** システムコード */
	private static final String	SYS_CD = "SYS_CD";
	
	/** ディレイド処理依頼種別コード */
	private static final String	DLYD_TRN_REQ_SBT_CD = "DLYD_TRN_REQ_SBT_CD";
	
	/** ディレイド処理結果コード */
	private static final String	DLYD_TRN_RSLT_CD = "DLYD_TRN_RSLT_CD";
	
	/** エラー電子ファイル管理番号 */
	private static final String	ERR_EFILE_KANRI_NO = "ERR_EFILE_KANRI_NO";
	
	/** エラー電子ファイル世代登録年月日時分秒 */
	private static final String	ERR_EFILE_GENE_ADD_DTM = "ERR_EFILE_GENE_ADD_DTM";
	
	/** 入力電子ファイル */
	private static final String	INPUT_EFILE = "INPUT_EFILE";
	
	/** 入力電子ファイル物理ファイル名 */
	private static final String	INPUT_EFILE_BUTSURI_NM = "INPUT_EFILE_BUTSURI_NM";
	
	/** 入力電子ファイルファイルサイズ */
	private static final String	INPUT_EFILE_SIZE = "INPUT_EFILE_SIZE";
	
	
	/**
	 * ディレイド処理依頼取得処理です。
	 * ｢依頼ジョブID｣と一致し、かつ｢処理実行日時｣が運用日付を超過、かつ処理依頼コードがNULLである処理依頼を取得します。
	 * 入力ファイルがある場合は、入力ファイルも取得します。
	 * 検索結果が0件の場合はNULLを返却します。
	 * ディレイド処理依頼ステータス　＝ 004(処理中）を検索対象とします。
	 * 
	 * @param cmnItem 業務共通電文
	 * @param reqJobId 依頼ジョブID
	 * @return infoMapList ディレイド処理依頼情報のHashMapが格納されたArrayList(依頼ジョブIDの昇順)HashMap内容は以下。<BR>
	 * <pre>
	 *  DLYD_TRN_REQ_NO          (String)   処理依頼を一意に特定するID
	 *  DLYD_TRN_REQ_STAT        (String)   ディレイド処理依頼の状態を表す。(依頼中/処理済/処理エラー)
	 *  INPUT_EFILE_KANRI_NO     (String)   入力ファイルを管理する電子ファイル管理を一意に識別する番号
	 *  INPUT_EFILE_GENE_ADD_DTM (String)   電子ファイル管理を一意に識別する日付
	 *  REQ_JOB_ID               (String)   処理依頼するバッチのジョブID(依頼先)
	 *  SYS_CD                   (String)   処理依頼を行った業務のシステムコード(依頼元)
	 *  DLYD_TRN_REQ_SBT_CD      (String)   処理依頼するバッチのジョブID(依頼先)
	 *  DLYD_TRN_RSLT_CD         (String)   バッチの実行結果を識別するコード(1:完了 / 2:業務エラー / 3:システムエラー)
	 *  ERR_EFILE_KANRI_NO       (String)   エラー電子ファイル管理を一意に識別する番号
	 *  ERR_EFILE_GENE_ADD_DTM   (String)   エラー電子ファイルを一意に識別する日付
	 *  INPUT_EFILE              (byte[])   実ファイル(解凍済)
	 *  INPUT_EFILE_BUTSURI_NM   (String)   zipファイルの名称
	 *  INPUT_EFILE_SIZE         (String)   元ファイルのバイト数(KB)
     * </pre>
	 * @throws Exception ディレイド処理依頼取得の取得に失敗した場合
	 */
	public static ArrayList<HashMap<String, Object>> getShoriIraiInfo(JBSbatCommonItem cmnItem,String reqJobId) throws JCCbatFrameworkException
	{

		// 業務共通電文チェック
		if (null == cmnItem)
		{
			throw new JCCbatFrameworkException("バッチ共通電文がnullです。");
		}
		
		// バッチ運用日チェック
		if (null == cmnItem.getOpeDate())
		{
			throw new JCCbatFrameworkException("バッチ運用日がnullです。");
		}
		
		// 依頼ジョブIDチェック
		if (null == reqJobId)
		{
			throw new JCCbatFrameworkException("依頼ジョブIDがnullです。");
		}		
		String id = reqJobId;
		id = id.replaceAll(" ","");		//半角空白削除
		id = id.replaceAll("　","");	//全角空白削除
		if ("".equals(id))
		{
			throw new JCCbatFrameworkException("依頼ジョブIDが空白です。");
		}
		if (!JBSbatCheckUtil.invoke(reqJobId ,new String[]{"hannkakuesuuji1"}))
		{
			throw new JCCbatFrameworkException("依頼ジョブIDのフォーマットが不正です。");
		}
		
		ArrayList infoMapList = null;
		JBSbatSQLAccess stmt = null;
		
		JBSbatCommonItem localCmnItem = null;
		JBSbatDBConnection dbconn = null;
		
		boolean rollback_bool = true;
		
		try
		{
			
			dbconn = new JBSbatDBConnection();
			
			localCmnItem = new JBSbatCommonItem();
			
			localCmnItem.setConnection(dbconn.conn);
			localCmnItem.setLogPrint(cmnItem.getLogPrint());
			localCmnItem.setSqlDefFilePath(cmnItem.getSqlDefFilePath());
			localCmnItem.setOnlineOpeDate(cmnItem.getOnlineOpeDate());
			localCmnItem.setOpeDate(cmnItem.getOpeDate());
			
			
			// ディレイド処理依頼情報リストを作成
			infoMapList =  new ArrayList();
			
			// ディレイド処理依頼テーブルアクセスを生成する
			stmt = new JBSbatSQLAccess(localCmnItem,"CC_T_DLYD_TRN_REQ");

			// 検索キーを設定する
			JBSbatCommonDBInterface dbList = new JBSbatCommonDBInterface();
			dbList.setValue(reqJobId);			// 依頼ジョブID
			// 20130513 FST)Yanagihara 運用日をオンライン運用日付に変更 start
			//dbList.setValue(cmnItem.getOpeDate() + "240000000");// バッチ運用日
			dbList.setValue(localCmnItem.getOnlineOpeDate() + JCCBatCommon.getSysDateTimeStamp().substring(8, 17));// オンライン運用日
			// 20130513 FST)Yanagihara 運用日をオンライン運用日付に変更 end
			
			stmt.selectBySqlDefine(dbList,"KK_SELECT_001");
			
			JBSbatCommonDBInterface inMap_forupdate = new JBSbatCommonDBInterface(); 
			ArrayList list_forupdate = new ArrayList();
			while(null != (inMap_forupdate = stmt.selectNext())){
				list_forupdate.add(inMap_forupdate.getString("DLYD_TRN_REQ_NO"));					// ディレイド処理依頼番号
			}
			
			// 検索結果が0件の場合NULLを返し処理を終了する。
			if(list_forupdate.size() == 0)
			{
				return null;
			}
			
			StringBuffer sb = new StringBuffer();
			sb.append("DLY.DLYD_TRN_REQ_NO IN (");
			
			for(int j = 0 ; j < list_forupdate.size() ; j++)
			{
//				JBSbatCommonDBInterface dbList_update = new JBSbatCommonDBInterface();
//				dbList_update.setValue(JCCbatGetSystemDateUtil.getSystemDateTime().get("sysDateTimeStamp"));
//				dbList_update.setValue(localCmnItem.getBatchUserId());	// オペレータアカウント
//				dbList_update.setValue(list_forupdate.get(j));
//				stmt.executeBySqlDefine(dbList_update, "CC_UPDATE_003");
				
				sb.append("'").append(list_forupdate.get(j)).append("'");
				if(j + 1 != list_forupdate.size())
				{
					sb.append(",");
				}
			}
			
			sb.append(")");
			
			// 依頼ジョブID,バッチ運用日を基にレコードを取得する
//			stmt.selectBySqlDefine(dbList,"CC_SELECT_001");
			String wkSql = stmt.getSql("CC_SELECT_003");
			wkSql = wkSql.replace("DLY.DLYD_TRN_REQ_NO IN (?)", sb.toString());
			stmt.setSqlMap("CC_SELECT_003", wkSql);

			// DBアクセスを実行します
			stmt.selectBySqlDefine(new JBSbatCommonDBInterface(), "CC_SELECT_003");


			JBSbatCommonDBInterface inMap = new JBSbatCommonDBInterface(); 
			HashMap<String, Object> outMap = null;
			while(null != (inMap = stmt.selectNext())){
				outMap =  new HashMap();
				outMap.put(DLYD_TRN_REQ_NO,inMap.getValue("DLYD_TRN_REQ_NO"));					// ディレイド処理依頼番号
				outMap.put(DLYD_TRN_REQ_STAT,inMap.getValue("DLYD_TRN_REQ_STAT"));				// ディレイド処理依頼ステータス
				outMap.put(INPUT_EFILE_KANRI_NO,inMap.getValue("INPUT_EFILE_KANRI_NO"));		// 入力電子ファイル管理番号
				outMap.put(INPUT_EFILE_GENE_ADD_DTM,inMap.getValue("INPUT_EFILE_GENE_ADD_DTM"));// 入力電子ファイル世代登録年月日時分秒
				outMap.put(REQ_JOB_ID,inMap.getValue("REQ_JOB_ID"));							// 依頼ジョブID
				outMap.put(SYS_CD,inMap.getValue("SYS_CD"));									// システムコード
				outMap.put(DLYD_TRN_REQ_SBT_CD,inMap.getValue("DLYD_TRN_REQ_SBT_CD"));			// ディレイド処理依頼種別コード
				outMap.put(DLYD_TRN_RSLT_CD,inMap.getValue("DLYD_TRN_RSLT_CD"));				// ディレイド処理結果コード
				outMap.put(ERR_EFILE_KANRI_NO,inMap.getValue("ERR_EFILE_KANRI_NO"));			// エラー電子ファイル管理番号
				outMap.put(ERR_EFILE_GENE_ADD_DTM,inMap.getValue("ERR_EFILE_GENE_ADD_DTM"));	// エラー電子ファイル世代登録年月日時分秒	
				outMap.put(INPUT_EFILE,getDenshiFileByte(cmnItem,(String)inMap.getValue("INPUT_EFILE_KANRI_NO")));		// 入力電子ファイル	
				outMap.put(INPUT_EFILE_BUTSURI_NM,inMap.getValue("INPUT_EFILE_BUTSURI_NM"));	// 入力電子ファイル物理ファイル名
				outMap.put(INPUT_EFILE_SIZE,inMap.getValue("INPUT_EFILE_SIZE"));				// 入力電子ファイルファイルサイズ	
				infoMapList.add(outMap);
			}
			// 検索結果が0件の場合NULLを返し処理を終了する。
			if(null == outMap){
				return null;
			}
			
			if (dbconn != null)
			{
//				dbconn.commit();
				rollback_bool = false;
			}
		}
		catch (Exception e)
		{
			throw new JCCbatFrameworkException( "ディレイド処理依頼取得処理で例外が発生しました。"+ e);
		}
		finally
		{
			//commit済みの場合、rollbackの必要がないため
			if (dbconn != null && rollback_bool)
			{
				try {
					dbconn.rollback();
				} catch (Exception e) {
					throw new JCCbatFrameworkException( "ディレイド処理依頼取得処理で例外が発生しました。"+ e);
				}
			}
			
			if (null != stmt)
			{
				try {
					stmt.close();
				} catch (SQLException e) {
					throw new JCCbatFrameworkException( "ディレイド処理依頼取得処理で例外が発生しました。"+ e);
				}
			}
			if (dbconn != null)
			{
				try {
					dbconn.closeConnection();
				} catch (Exception e) {
					throw new JCCbatFrameworkException( "ディレイド処理依頼取得処理で例外が発生しました。"+ e);
				}
			}
			

		}
		
		return infoMapList;
	}

//	/**
//	 * ディレイド処理依頼結果更新処理です。
//	 * バッチの処理結果を｢処理依頼｣テーブルへ登録(UPDATE)します。
//	 * またエラー指定時は、エラーファイルを文書管理テーブルに登録し、文書管理番号をエラーファイル番号へ格納します。
//	 * 
//	 * @param cmnItem 業務共通電文
//	 * @param dlydIrnReqNo 処理依頼番号
//	 * @param dlyTrnRsltCd ディレイド処理依頼結果コード（1：完了、2：業務エラー、3：システムエラー）
//	 * @param errorFilePath 業務エラー時に出力するエラーファイルのフルパス。正常時はNULL。
//	 * @return 処理依頼更新結果マップ（処理依頼結果登録した処理依頼番号(String)、業務エラー時に登録するエラーファイルの電子ファイル管理番号(String)）
//	 * @throws JCCbatFrameworkException 
//	 */
//	public static HashMap<String,String> updateShoriIraiResult(JBSbatCommonItem cmnItem, String dlydIrnReqNo,
//			String dlyTrnRsltCd,String errorFilePath) throws JCCbatFrameworkException
//	{
//		// 業務共通電文チェック
//		if (null == cmnItem)
//		{
//			throw new JCCbatFrameworkException("バッチ共通電文がnullです。");
//		}
//		
//		// 処理依頼番号チェック
//		String strDlydIrnReqNo = null;
//		if(null != dlydIrnReqNo){
//			strDlydIrnReqNo = JPCEditString.trim(dlydIrnReqNo);
//		}
//		if (null == dlydIrnReqNo || true == "".equals(strDlydIrnReqNo))
//		{
//			throw new JCCbatFrameworkException("処理依頼番号がnullもしくは空白です");
//		}
//		if(!JCCBatCommon.isKetasuu1(dlydIrnReqNo, "15") || !JCCBatCommon.isHannkakuESuuji1(dlydIrnReqNo))
//		{
//			throw new JCCbatFrameworkException("処理依頼番号の桁数(15桁)が不正もしくは半角英数字ではありません");
//		}
//		
//		// 処理依頼結果コードチェック
//		String strDlyTrnRsltCd = null;
//		if(null != dlyTrnRsltCd){
//			strDlyTrnRsltCd = JPCEditString.trim(dlyTrnRsltCd);
//		}
//		if (null == dlyTrnRsltCd || true == "".equals(strDlyTrnRsltCd))
//		{
//			throw new JCCbatFrameworkException("処理依頼結果コードがnullもしくは空白です");
//		}
//		if(!JCCBatCommon.isKetasuu1(dlyTrnRsltCd, "1") || !JCCBatCommon.isHannkakuSuuji1(dlyTrnRsltCd))
//		{
//			throw new JCCbatFrameworkException("処理依頼結果コードの桁数(1桁)が不正もしくは半角数字ではありません");
//		}
//		
//		// エラーファイルパスチェック
//		String strerrorFilePath = null;
//		if(null != errorFilePath){
//			strerrorFilePath = JPCEditString.trim(errorFilePath);
//		}
//		if (true == "".equals(strerrorFilePath))
//		{
//			throw new JCCbatFrameworkException("エラーファイルパスが空白です");
//		}
//		
//
//		String docNo = null;		// 電子ファイル管理番号
//		String sedaiDate = null;   // 世代登録年月日月日時分秒
//		
//		if(null != errorFilePath)	// 引数にエラーファイルパスが入力されている場合
//		{
//			try {
//				// 電子ファイル登録部品呼び出し
//				String strRet[] = JCCBatCommon.createDenshiFile(cmnItem, "0000", errorFilePath, null);
//				docNo 	  = strRet[0];
//				sedaiDate = strRet[1];
//				
//			} catch (Exception e) {
//				throw new JCCbatFrameworkException( "ディレイド処理依頼取得処理で例外が発生しました" + e);
//			}
//			
//		}
//		
//		JBSbatSQLAccess stmt = null;
//		try {
//			// ディレイド処理依頼テーブルアクセスを生成する
//			stmt = new JBSbatSQLAccess(cmnItem,"CC_T_DLYD_TRN_REQ");
//			
//			// 検索キーを設定する
//			JBSbatCommonDBInterface dbList = new JBSbatCommonDBInterface();
//			dbList.setValue(dlyTrnRsltCd);	// ディレイド処理依頼結果コード
//			if("1".equals(dlyTrnRsltCd)){   // ディレイド処理依頼ステータス
//				// 処理済を設定
//				dbList.setValue("002"); 
//			}else{
//				// 処理エラーを設定				
//				dbList.setValue("003");
//			}
//			if(null != errorFilePath)	// 引数にエラーファイルパスが入力されている場合
//			{
//				dbList.setValue(docNo); 	// エラー電子ファイル管理番号
//				dbList.setValue(sedaiDate); // エラー電子ファイル世代登録年月日時分秒
//			}
//			// システム日付
//			dbList.setValue(JCCbatGetSystemDateUtil.getSystemDateTime().get("sysDateTimeStamp"));
//			dbList.setValue(cmnItem.getBatchUserId());	// オペレータアカウント
//			dbList.setValue(strDlydIrnReqNo);			// 処理依頼番号
//			
//			//SQL実行
//			if(null != errorFilePath)	// 引数にエラーファイルパスが入力されている場合
//			{
//				stmt.executeBySqlDefine(dbList, "CC_UPDATE_001");
//			}else{
//				stmt.executeBySqlDefine(dbList, "CC_UPDATE_002");
//			}
//			
//		} 
//		catch (Exception e)
//		{
//			throw new JCCbatFrameworkException( "ディレイド処理依頼取得処理で例外が発生しました" + e);
//		}
//		finally
//		{
//			if (null != stmt)
//			{
//				try {
//					stmt.close();
//				} catch (SQLException e) {
//					;//なにもしない
//				}
//			}
//
//		}
//		
//		HashMap<String,String> ret = new HashMap<String,String>();
//		ret.put("DLYD_TRN_REQ_NO", dlydIrnReqNo);
//		ret.put("EFILE_KAMRI_NO", docNo);
//		
//		return ret;
//	}

	/**
	 * BLOB型のデータをbyteの配列に変換します。
	 * 
	 * @param blobData BLOB型のデータ
	 * @return 変換後のbyteの配列
	 * @throws Exception 
	 * @throws SQLException 
	 */
//	private static byte[] getBlobByte(BLOB blobData) throws Exception
//	{
//		if(blobData == null){
//			return null;
//		}
//		// ここでファイル解凍部品(JCCModelCommon.uncompressFile)を呼ぶ予定
//		// 引数などのインターフェイスが不明なため未実装
//		
//		int size = 0;
//		byte reBuf[] = null;
//		InputStream in;
//		
//		size = blobData.getBufferSize();
//		reBuf = new byte[size];
//		in = blobData.binaryStreamValue();
//		in.read(reBuf);
//		
//		reBuf = getKariFileData(); //電子ファイル管理処理ができるまでの暫定処理
//		
//		return reBuf;
//	}
	
	/**
	 * 電子ファイル管理処理が完成するまでの暫定処理です。
	 * 
	 * @return 変換後のbyteの配列
	 * @throws Exception 
	 */
//	private static byte[] getKariFileData() throws Exception
//	{
//		final String FILE_NAME = "C:\\tmp\\input.bin";
//		byte reb[] = null; 
//		
//		FileInputStream in = new FileInputStream( FILE_NAME );
//		ByteArrayOutputStream baos = new ByteArrayOutputStream();
//		byte btmp[] = new byte[1024]; 
//		int j;
//		while((j = in.read(btmp))!=-1){
//			baos.write(btmp, 0, j);
//		}
//		
//		reb = baos.toByteArray();
//		
//		if(in != null){
//			in.close();
//		}
//
//		return reb;
//	}
	
	/**
	 * 電子ファイルをbyteの配列に変換します。
	 * 
	 * @param cmnItem 業務共通電文クラス
	 * @param eFileKanriNo 電子ファイル管理番号
	 * @return 変換後のbyteの配列
	 * @throws Exception 
	 * @throws SQLException 
	 */
	private static byte[] getDenshiFileByte(JBSbatCommonItem cmnItem,String eFileKanriNo) throws Exception
	{
		if(null == eFileKanriNo || "".equals(eFileKanriNo)){
			return null;
		}
		BufferedInputStream in = null;
		ByteArrayOutputStream baos = null;
		byte reb[] = null; 
		String path = null;
		
		try
		{
			
			// 電子ファイル解凍処理
			path = JCCbatDenshiFileUtil.searchDenshiFile(cmnItem, eFileKanriNo);
			
			if(null == path){
				return null;
			}
			
			in = new BufferedInputStream(new FileInputStream( path ));
			baos = new ByteArrayOutputStream();
			byte btmp[] = new byte[1024]; 
			int j;
			while((j = in.read(btmp))!=-1){
				baos.write(btmp, 0, j);
			}
			
			reb = baos.toByteArray();
			
			if(null != in){
				in.close();
			}
			if(null != baos){
				baos.close();
			}
		}
		catch (Exception e)
		{
			throw new JCCbatFrameworkException( "ファイルをbyteの配列変換に失敗しました。" + e);
		}
		finally
		{
			//作業用ファイルの削除
			if(null != path){
				String parentPath = path.substring(0, path.lastIndexOf(File.separator));
				JCCFileUtil.removeDir(parentPath);
			}

			
			if (null != in)
			{
				try {
					in.close();
				} catch (Exception e) {
					;//なにもしない
				}
			}
			if (null != baos)
			{
				try {
					baos.close();
				} catch (Exception e) {
					;//なにもしない
				}
			}

		}

		return reb;
	}
	

}
