/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom						 *
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatKKHisDelToolOpSvcKei
*	ソースファイル名	：JBSbatKKHisDelToolOpSvcKei.java
*	作成者				：富士通　
*	作成日				：2014年07月01日
*＜機能概要＞
*　オプションサービス契約削除部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2014/07/01  FJ)山下		新規作成
*	v9.00.00	2014/08/03  FJ)山下		ST4-2014-0000048 
*********************************************************************/
package eo.business.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;

import eo.framework.db.JBSbatSQLAccess;
import eo.framework.item.JBSbatCommonDBInterface;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.item.JBSbatServiceInterfaceMap;

/**
* 入力ファイルに記述されたキーを元に、物理削除を行います。<BR>
* <BR>
* 物理削除対象テーブル<BR>
* KK0351	オプションサービス契約				KK_T_OP_SVC_KEI
* KK0361	オプションサービス契約<ISP>			KK_T_OPSVKEI_ISP
* KK0371	オプションサービス契約<電話>		KK_T_OPSVKEI_TEL
* KK0381	オプションサービス契約<TV>			KK_T_OPSVKEI_TV
* <BR>
* 入力ファイルとテーブルの対応は以下の通りです。<BR>
* KK0351:KKIFM616012.csv<BR>
* KK0361:KKIFM616013.csv<BR>
* KK0371:KKIFM616014.csv<BR>
* KK0381:KKIFM616015.csv<BR>
* <BR>
* @author 富士通
*/
public class JBSbatKKHisDelToolOpSvcKei extends JBSbatKKAbstractHistoryDeleteTool
{
	
	/** テーブル(オプションサービス契約)*/
	private static final String D_TBL_NAME_KK_T_OP_SVC_KEI = "KK_T_OP_SVC_KEI";
	/** テーブル(オプションサービス契約(ISP))*/
	private static final String D_TBL_NAME_KK_T_OPSVKEI_ISP = "KK_T_OPSVKEI_ISP";
	/** テーブル(オプションサービス契約(電話))*/
	private static final String D_TBL_NAME_KK_T_OPSVKEI_TEL = "KK_T_OPSVKEI_TEL";
	/** テーブル(オプションサービス契約(TV))*/
	private static final String D_TBL_NAME_KK_T_OPSVKEI_TV = "KK_T_OPSVKEI_TV";
	
	/** テーブルアクセスクラス(オプションサービス契約)*/
	private JBSbatSQLAccess db_KK_T_OP_SVC_KEI = null;
	/** テーブルアクセスクラス(オプションサービス契約(ISP))*/
	private JBSbatSQLAccess db_KK_T_OPSVKEI_ISP = null;
	/** テーブルアクセスクラス(オプションサービス契約(電話))*/
	private JBSbatSQLAccess db_KK_T_OPSVKEI_TEL = null;
	/** テーブルアクセスクラス(オプションサービス契約(TV))*/
	private JBSbatSQLAccess db_KK_T_OPSVKEI_TV = null;

	/** キー：オプションサービス契約番号 */
	private static final String OP_SVC_KEI_NO = "OP_SVC_KEI_NO";
	/** キー：世代年月日時分秒 */
	private static final String GENE_ADD_DTM = "GENE_ADD_DTM";
	
	/** 入力ファイル項目数 */
	private static final int COL_NUM = 2;
	
	/** オプションサービス契約番号桁数 */
	private static final int OP_SVC_KEI_NO_LENGTH = 12;
	/** 世代年月日時分秒桁数 */
	private static final int GENE_ADD_DTM_LENGTH = 17;
	
	/** 入力ファイル(KK0351) */
	private static final String DEL_UNLOAD_FILE_KK0351 = "KKIFM616012.csv";
	/** 入力ファイル(KK0361) */
	private static final String DEL_UNLOAD_FILE_KK0361 = "KKIFM616013.csv";
	/** 入力ファイル(KK0371) */
	private static final String DEL_UNLOAD_FILE_KK0371 = "KKIFM616014.csv";
	/** 入力ファイル(KK0381) */
	private static final String DEL_UNLOAD_FILE_KK0381 = "KKIFM616015.csv";
	/** タイムアウト後の入力データを保持するリスト **/
	private ArrayList<String>listTimeOver = null;
	
	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws SQLException 
	 * @throws IOException 
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws IOException, SQLException 
	{
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);

		// DBアクセスクラスを生成します
		// KK0351	オプションサービス契約				KK_T_OP_SVC_KEI
		db_KK_T_OP_SVC_KEI = new JBSbatSQLAccess(commonItem, D_TBL_NAME_KK_T_OP_SVC_KEI);
		// KK0361	オプションサービス契約<ISP>			KK_T_OPSVKEI_ISP
		db_KK_T_OPSVKEI_ISP = new JBSbatSQLAccess(commonItem, D_TBL_NAME_KK_T_OPSVKEI_ISP);
		// KK0371	オプションサービス契約<電話>		KK_T_OPSVKEI_TEL
		db_KK_T_OPSVKEI_TEL = new JBSbatSQLAccess(commonItem, D_TBL_NAME_KK_T_OPSVKEI_TEL);
		// KK0381	オプションサービス契約<TV>			KK_T_OPSVKEI_TV
		db_KK_T_OPSVKEI_TV = new JBSbatSQLAccess(commonItem, D_TBL_NAME_KK_T_OPSVKEI_TV);
		
		if (!this.checkFreeItem())
		{
			this.skip();
			return;
		}
		
		// 引数から起動時間を設定
		setStartUpTime(new Integer(commonItem.getFreeItem()));
		
		// 起動時間を設定
		setStartTimeMills(System.currentTimeMillis());
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception 
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap) throws Exception 
	{
		super.logPrint.printDebugLog("execute_START");
		
		// 出力共通電文を生成する。
		JBSbatOutputItem outputBean = new JBSbatOutputItem();
		
		// 入力ファイルパスを取得
		String filePath = inMap.getString(INFILE_KEY);
		
		// 入力ファイルチェックに該当した場合
		if (!checkInFile(filePath))
		{
			// 次のファイルへ移行
			return outputBean;
		}
		
		// 入力ファイル
		File inFile = new File(filePath);
		
		BufferedReader br = new BufferedReader(new FileReader(inFile));
		
		// 時間切れフラグ
		boolean isTimeOverFlg = false;
		
		// サポート対象外フラグ
		boolean isUnsupportFileFlg = false;
		
		// 行数
		int lineNumber = 1;
		// 行
		String line;
		//ST4-2014-0000048 ADD START
		// タイムアウト後の入力データを保持するリスト
		listTimeOver = new ArrayList<String>();
		//ST4-2014-0000048 ADD END
		while ((line = br.readLine()) != null)
		{
			
			// 起動時間チェック
			if (isTimeOverFlg || this.isTimeOver())
			{
				//ST4-2014-0000048 MOD START
				// 時間切れフラグを設定し、ループ処理を終了
				isTimeOverFlg = true;
			
//				break;
				listTimeOver.add(line);
				
				continue;
				//ST4-2014-0000048 MOD EMD
			}
			
			// 入力値チェックに該当した場合
			if ( !this.checkParams(line, lineNumber) )
			{
				// 行数繰上げ
				lineNumber++;
				// 次行へ移行
				continue;
			}
			
			// 内容項目取得
			String[] cols = line.replaceAll(DOUBLE_QUOTE, BLANK).split(COMMA);
			// オプションサービス契約番号を取得(入力ファイルのN行目)
			String opSvcKeiNo = cols[0];
			// 世代年月日時分秒を取得(入力ファイルのN行目)
			String geneAddDtm = cols[1];
			
			// キー情報を生成
			LinkedHashMap<String, String> deleteMap = new LinkedHashMap<String, String>();
			deleteMap.put(OP_SVC_KEI_NO, opSvcKeiNo);
			deleteMap.put(GENE_ADD_DTM, geneAddDtm);
			
			//ST4-2014-0000048 DEL START
			/**
			// KK0351	オプションサービス契約	KK_T_OP_SVC_KEI
			if (DEL_UNLOAD_FILE_KK0351.equals(inFile.getName()))
			{
				int svcKeiDelCount = this.executeKK_T_OP_SVC_KEI_PKDELETE(opSvcKeiNo, geneAddDtm);
				this.printDeleteLog(D_TBL_NAME_KK_T_OP_SVC_KEI, deleteMap, svcKeiDelCount, inFile.getName());
			}
			**/
			//ST4-2014-0000048 DEL END
			// KK0361	オプションサービス契約<ISP>	KK_T_OPSVKEI_ISP
			if (DEL_UNLOAD_FILE_KK0361.equals(inFile.getName()))
			{
				//ST4-2014-0000048 ADD START
				int svcKeiDelCount = this.executeKK_T_OP_SVC_KEI_PKDELETE(opSvcKeiNo, geneAddDtm);
				this.printDeleteLog(D_TBL_NAME_KK_T_OP_SVC_KEI, deleteMap, svcKeiDelCount, inFile.getName());
				//ST4-2014-0000048 ADD END

				int svcKeiEohNetDelCount = this.executeKK_T_OPSVKEI_ISP_PKDELETE(opSvcKeiNo, geneAddDtm);
				this.printDeleteLog(D_TBL_NAME_KK_T_OPSVKEI_ISP, deleteMap, svcKeiEohNetDelCount, inFile.getName());
			}
			// KK0371	オプションサービス契約<電話>	KK_T_OPSVKEI_TEL
			else if (DEL_UNLOAD_FILE_KK0371.equals(inFile.getName()))
			{
				//ST4-2014-0000048 ADD START
				int svcKeiDelCount = this.executeKK_T_OP_SVC_KEI_PKDELETE(opSvcKeiNo, geneAddDtm);
				this.printDeleteLog(D_TBL_NAME_KK_T_OP_SVC_KEI, deleteMap, svcKeiDelCount, inFile.getName());
				//ST4-2014-0000048 ADD END
				int svcKeiEohTvDelCount = this.executeKK_T_OPSVKEI_TEL_PKDELETE(opSvcKeiNo, geneAddDtm);
				this.printDeleteLog(D_TBL_NAME_KK_T_OPSVKEI_TEL, deleteMap, svcKeiEohTvDelCount, inFile.getName());
			}
			// KK0381	オプションサービス契約<TV>		KK_T_OPSVKEI_TV
			else if (DEL_UNLOAD_FILE_KK0381.equals(inFile.getName()))
			{
				//ST4-2014-0000048 ADD START
				int svcKeiDelCount = this.executeKK_T_OP_SVC_KEI_PKDELETE(opSvcKeiNo, geneAddDtm);
				this.printDeleteLog(D_TBL_NAME_KK_T_OP_SVC_KEI, deleteMap, svcKeiDelCount, inFile.getName());
				//ST4-2014-0000048 ADD END
				int svcKeiEohTelDelCount = this.executeKK_T_OPSVKEI_TV_PKDELETE(opSvcKeiNo, geneAddDtm);
				this.printDeleteLog(D_TBL_NAME_KK_T_OPSVKEI_TV, deleteMap, svcKeiEohTelDelCount, inFile.getName());
			}
			else
			{
				super.logPrint.printDebugLog("サポート対象外のファイルが指定されています。" + inFile.getPath());
				isUnsupportFileFlg = true;
				break;
			}
			
			lineNumber++;
		}
		
		br.close();
		
		// 時間切れの場合
		if (isTimeOverFlg)
		{
			// 引数で指定した起動時間を超えていたら終了
			this.skip();
			this.printTimeOverLog();
		}
		
		// サポート対象外ファイルでない場合
		if (!isUnsupportFileFlg)
		{
			createNewInFile(filePath);
		}
		
		super.logPrint.printDebugLog("execute_END");
		
		return outputBean;
	}

	/**
	 * 業務サービス終了処理
	 * @throws SQLException 
	 */
	public void terminal() throws SQLException 
	{
		super.printTotalDeleteLog();
		
		// DBアクセスクラスをクローズします
		db_KK_T_OP_SVC_KEI.close();
		db_KK_T_OPSVKEI_ISP.close();
		db_KK_T_OPSVKEI_TEL.close();
		db_KK_T_OPSVKEI_TV.close();
	}
	
	/**
	 * オプションサービス契約テーブルに対して主キーで物理削除を行います。
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param geneAddDtm 世代年月日時分秒
	 * @return 削除件数
	 * @throws Exception
	 */
	private int executeKK_T_OP_SVC_KEI_PKDELETE(String opSvcKeiNo, String geneAddDtm) throws Exception 
	{
		// 条件のマップを作成します
		JBSbatCommonDBInterface whereMap = new JBSbatCommonDBInterface();
		whereMap.setValue(OP_SVC_KEI_NO, opSvcKeiNo);
		whereMap.setValue(GENE_ADD_DTM, geneAddDtm);

		// DBアクセスを実行します
		return db_KK_T_OP_SVC_KEI.deleteByPrimaryKeys(whereMap);
	}
	
	/**
	 * オプションサービス契約<ISP>に対して主キーで物理削除を行います。
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param geneAddDtm 世代年月日時分秒
	 * @return 削除件数
	 * @throws Exception
	 */
	private int executeKK_T_OPSVKEI_ISP_PKDELETE(String opSvcKeiNo, String geneAddDtm) throws Exception
	{
		// 条件のマップを作成します
		JBSbatCommonDBInterface whereMap = new JBSbatCommonDBInterface();
		whereMap.setValue(OP_SVC_KEI_NO, opSvcKeiNo);
		whereMap.setValue(GENE_ADD_DTM, geneAddDtm);

		// DBアクセスを実行します
		return db_KK_T_OPSVKEI_ISP.deleteByPrimaryKeys(whereMap);
	}
	
	/**
	 * オプションサービス契約<電話>テーブルに対して主キーで物理削除を行います。
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param geneAddDtm 世代年月日時分秒
	 * @return 削除件数
	 * @throws Exception
	 */
	private int executeKK_T_OPSVKEI_TEL_PKDELETE(String opSvcKeiNo, String geneAddDtm) throws Exception
	{
		// 条件のマップを作成します
		JBSbatCommonDBInterface whereMap = new JBSbatCommonDBInterface();
		whereMap.setValue(OP_SVC_KEI_NO, opSvcKeiNo);
		whereMap.setValue(GENE_ADD_DTM, geneAddDtm);

		// DBアクセスを実行します
		return db_KK_T_OPSVKEI_TEL.deleteByPrimaryKeys(whereMap);
	}
	
	/**
	 * オプションサービス契約<TV>テーブルに対して主キーで物理削除を行います。
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param geneAddDtm 世代年月日時分秒
	 * @return 削除件数
	 * @throws Exception
	 */
	private int executeKK_T_OPSVKEI_TV_PKDELETE(String opSvcKeiNo, String geneAddDtm) throws Exception
	{
		// 条件のマップを作成します
		JBSbatCommonDBInterface whereMap = new JBSbatCommonDBInterface();
		whereMap.setValue(OP_SVC_KEI_NO, opSvcKeiNo);
		whereMap.setValue(GENE_ADD_DTM, geneAddDtm);

		// DBアクセスを実行します
		return db_KK_T_OPSVKEI_TV.deleteByPrimaryKeys(whereMap);
	}

	/**
	 * 入力パラメータのチェックを行います。
	 * @param opSvcKeiNo オプションサービス契約番号
	 * @param geneAddDtm 世代年月日時分秒
	 * @return 判定結果
	 */
	private boolean checkParams(String line, int lineNumber)
	{
		String[] cols = line.replaceAll(DOUBLE_QUOTE, BLANK).split(COMMA);
		
		if (COL_NUM != cols.length)
		{
			super.logPrint.printDebugLog(lineNumber + "行目：項目数が不正です。");
			return false;
		}
		
		// オプションサービス契約番号を取得(入力ファイルのN行目)
		String opSvcKeiNo = cols[0];
		// 世代年月日時分秒を取得(入力ファイルのN行目)
		String geneAddDtm = cols[1];
		
		if ( (null == opSvcKeiNo|| "".equals(opSvcKeiNo)) )
		{
			super.logPrint.printDebugLog(lineNumber + "行目：オプションサービス契約番号が入力されていません。");
			return false;
		}
		
		if ( (null == geneAddDtm || "".equals(geneAddDtm)) )
		{
			super.logPrint.printDebugLog(lineNumber + "行目：世代年月日時分秒が入力されていません。");
			return false;
		}
		
		if (opSvcKeiNo.length() != OP_SVC_KEI_NO_LENGTH)
		{
			super.logPrint.printDebugLog(lineNumber + "行目：オプションサービス契約番号が" + OP_SVC_KEI_NO_LENGTH + "桁ではありません。");
			return false;
		}
		
		if (geneAddDtm.length() != GENE_ADD_DTM_LENGTH)
		{
			super.logPrint.printDebugLog(lineNumber + "行目：世代年月日時分秒が" + GENE_ADD_DTM_LENGTH + "桁ではありません。");
			return false;
		}
		
		return true;
	}

	/**
	 * 削除した行を取り除いた入力ファイルを作成します。
	 * 
	 * @param filePath 入力ファイルパス
	 * @exception IOException
	 */
	@Override
	void createNewInFile(String filePath) throws IOException {
		
		// 入力ファイルチェック
		if (!checkInFile(filePath))
		{
			return;
		}
	
		// 入力ファイル
		File inFile = new File(filePath);
		
		/**
		// 削除キー情報リスト
		ArrayList<LinkedHashMap<String, String>> list = null;
		
		// 入力ファイル毎の削除キー情報がある場合
		if (null != this.tableDeleteInfoMap && this.tableDeleteInfoMap.containsKey(inFile.getName()))
		{
			// 削除キー情報リストを取得
			list = this.tableDeleteInfoMap.get(inFile.getName());
		}
		*/
		
		// 入力ファイルから、削除した行を除いた入力ファイル
		File newInFile = new File(inFile.getParentFile().getPath() + "/" + inFile.getName() + ".new");
		
		BufferedWriter bw = new BufferedWriter(new FileWriter(newInFile));
//		BufferedReader br = new BufferedReader(new FileReader(inFile));
		
		
		for(int i = 0 ; i < listTimeOver.size() ; i ++) {

			String line = listTimeOver.get(i);
/**
		while ((line = br.readLine()) != null)
		{
			// 内容項目取得
			String[] cols = line.replaceAll(DOUBLE_QUOTE, BLANK).split(COMMA);
			// オプションサービス契約番号を取得(入力ファイルのN行目)
			String opSvcKeiNo = cols[0];
			// 世代年月日時分秒を取得(入力ファイルのN行目)
			String geneAddDtm = cols[1];
			
			LinkedHashMap<String, String> deleteMap = new LinkedHashMap<String, String>();
			deleteMap.put(OP_SVC_KEI_NO, opSvcKeiNo);
			deleteMap.put(GENE_ADD_DTM, geneAddDtm);
			
			// 削除キー情報リストにある場合
			if (null != list && list.contains(deleteMap))
			{
				// 出力しない
				continue;
			}
*/			
			bw.write(line);
			bw.newLine();
		}
		
//		br.close();
		
		bw.flush();
		bw.close();
		
		// 入力ファイルを置き換え
		if (inFile.delete())
		{
			newInFile.renameTo(new File(filePath));
		}
	}



}
