/*********************************************************************
*	All Right reserved,Copyright (c) Fujitsu, 2011
**********************************************************************
*＜プログラム内容＞
*	システム名		：Futurity
*	モジュール名	：JCCbatShoriIraiUtil
*	ソースファイル名：JCCbatShoriIraiUtil.java
*	作成者			：富士通
*	日付			：2011年04月08日
*＜機能概要＞
*	ディレイド処理依頼の確認、および、結果登録を行います。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/04/08	富士通		新規作成
*
**********************************************************************/

package eo.business.common;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import oracle.sql.BLOB;

import eo.common.util.JCCFileUtil;
import eo.common.util.JPCEditString;
import eo.framework.application.JCCbatFrameworkException;
import eo.framework.db.JBSbatSQLAccess;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.util.JBSbatCheckUtil;
import eo.framework.util.JCCbatGetSystemDateUtil;


/**
 * ディレイド処理依頼の確認、および、結果登録を行います。getKariFileData
 * <br>
 * @author 富士通
 */
public class JACbatShoriIraiUtil {

	/** ディレイド処理依頼番号 */
	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を返却します。
	 * 
	 * @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;
		try
		{
			// ディレイド処理依頼情報リストを作成
			infoMapList =  new ArrayList();
			
			// ディレイド処理依頼テーブルアクセスを生成する
			stmt = new JBSbatSQLAccess(cmnItem,"CC_T_DLYD_TRN_REQ");

			// 検索キーを設定する
			JBSbatCommonDBInterface dbList = new JBSbatCommonDBInterface();
			dbList.setValue(reqJobId);			// 依頼ジョブID
			dbList.setValue(cmnItem.getOpeDate() + "240000000");// バッチ運用日
			
			// 依頼ジョブID,バッチ運用日を基にレコードを取得する
			stmt.selectBySqlDefine(dbList,"CC_SELECT_001");
			

			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;
			}
			
		}
		catch (Exception e)
		{
			throw new JCCbatFrameworkException( "ディレイド処理依頼取得処理で例外が発生しました。"+ e);
		}
		finally
		{
			if (null != stmt)
			{
				try {
					stmt.close();
				} catch (SQLException 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 
	 */
	public 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;
	}

}
