/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatKKFileSplitForCo
*	ソースファイル名	：JBSbatKKFileSplitForCo.java
*	作成者				：富士通　
*	作成日				：2015年11月25日
*＜機能概要＞
*　ファイル分割（コンテンツ）部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2015/11/25   富士通		新規作成
*	v20.00.01	2015/12/14   FJ)木庭	【IT1-2015-0000151】ファイル出力項目修正
*	v20.00.02	2015/12/15   FJ)木庭	【IT2-2015-0000043】for文の処理を変更
*
*********************************************************************/
package eo.business.service;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import eo.business.common.JBSbatBusinessService;
import eo.business.common.JKKBatConst;
import eo.business.util.file.JBSbatKKIFM676;
import eo.common.constant.JPCBatchMessageConstant;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.util.JBSbatStringUtil;
import eo.framework.application.JBSbatBusinessException;

/**
* ファイル分割（コンテンツ） <p>
*<BR>
* @author 富士通
*/
public class JBSbatKKFileSplitForCo extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/
	/** カード預りID対象クレジットカード番号ファイル（Ｃｏ）のファイルパス */
	protected String filePassCo = "";
	
	/** カード預りID対象クレジットカード番号ファイル（Ｃｏ）中間２のファイルパス */
	protected String filePassMid2 = "";
	
	/** ファイル分割（Ｃｏ）のファイルパス */
	protected String filePassSplit = "";
	
	/** 課金対象年月 */
	protected static final String CHRG_TRGT_YM = "CHRG_TRGT_YM";
	
	/** 請求契約番号 */
	protected static final String SEIKY_KEI_NO = "SEIKY_KEI_NO";
	
	/** クレジットカード番号 */
	protected static final String CRECARD_NO = "CRECARD_NO";
	
	/** 請求方法番号 */
	protected static final String SEIKY_WAY_NO_CRECARD = "SEIKY_WAY_NO_CRECARD";
	
	/** 請求番号 */
	protected static final String SEIKY_NO = "SEIKY_NO";
	
	/** 仕向先会社コード */
	protected static final String SHIKOSAKI_COMP_CD = "SHIKOSAKI_COMP_CD";
	
	/** 入力会員番号 */
	protected static final String INPUT_MEMBER_NUMBER = "INPUT_MEMBER_NUMBER";
	
	/** 入力有効期限 */
	protected static final String INPUT_YK_KIGEN = "INPUT_YK_KIGEN";
	
	/** クレジットカードID */
	protected static final String CRECARD_ID = "CRECARD_ID";
	
	/** クレジットカード番号預りID */
	protected static final String CRECARD_NO_AZKRI_ID = "CRECARD_NO_AZKRI_ID";

	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
		
		// フリー項目値の取得をします。
		String[] free_item = commonItem.getFreeItem().split(JKKBatConst.S_PARAM_DELIM);
		
		// カード預りID対象クレジットカード番号ファイル（ＩＳＰ）の取得
		filePassCo = free_item[0];
		
		// カード預りID対象クレジットカード番号ファイル（ＩＳＰ）中間２の取得
		filePassMid2 = free_item[1];
		
		// ファイル分割（ＩＳＰ）の取得
		filePassSplit = free_item[2];
		
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		// 2．ファイル入力：カード預りＩＤ対象クレジットカード番号ファイル（ＩＳＰ）
		List<Map<String, String>> ispList = getIspFile();
		
		// 3．ファイル入力：カード預りＩＤ対象クレカ番号ファイル（ＩＳＰ）中間２
		List<Map<String, String>> mid2List = getMid2File();
		
		// 4．ファイル出力：ファイル分割（ＩＳＰ）
		// 4．2 マージ処理
		List<Map<String, String>> mergeList = getMergeList(ispList, mid2List);
		
		// 4．3 ファイル出力
		// 4．2のデータをクレジットカードID末尾1桁単位に、ファイルに出力する（10分割）
		// データ分割用List作成
		Map<Integer, List<Map<String, String>>> outputMap = new HashMap<Integer, List<Map<String, String>>>();
		for(int i = 0; i < 10; ++i)
		{
			outputMap.put(i, new ArrayList<Map<String, String>>());
		}
		
		// データ分割(クレジットカードID末尾1桁単位)
		setSplitData(outputMap, mergeList);
		
		// ファイル出力
		outputFile(outputMap);
		
		return null;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}
	/**
	 * データ分割(クレジットカードID末尾1桁単位)の設定
	 * @param outputList
	 * @param mergeList
	 */
	private void setSplitData(
			Map<Integer, List<Map<String, String>>> outputList,
			List<Map<String, String>> mergeList) {
		
		for(Map<String, String> merge : mergeList)
		{
			// クレジットカードID取得
			String crecardId = merge.get(CRECARD_ID);
			
			// クレジットカードIDの末尾1桁取得
			String numStr = crecardId.substring(crecardId.length() -1, crecardId.length());
			
			// データを末尾1桁のListに追加			
			outputList.get(Integer.parseInt(numStr)).add(merge);
		}
	}

	/**
	 * ファイル出力
	 * @param outputMap
	 * @throws Exception 
	 */
	private void outputFile(Map<Integer, List<Map<String, String>>> outputMap) throws Exception {
		
		for(int i = 0; i < 10; ++i)
		{	
			// 対象List取得
			List<Map<String, String>> outputList = outputMap.get(i);
			
			// ファイル作成
			StringBuilder filePass = new StringBuilder();
			filePass.append(filePassSplit);
			filePass.append(String.format("%03d", i));
			filePass.append(".csv");
			BufferedWriter out = null;
			
			try {
			
				out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filePass.toString()), JKKBatConst.S_CHR_CODE));
			
				// ファイル書き込み
				for(Map<String, String> outMap : outputList)
				{
					StringBuilder sb = new StringBuilder();
					sb.append(outMap.get(CRECARD_ID)); // クレジットカードID
					sb.append(JKKBatConst.S_SEP_CAM);
// IT1-2015-0000151 DEL START
//					sb.append(outMap.get(SHIKOSAKI_COMP_CD)); // 仕向先会社コード
//					sb.append(JKKBatConst.S_SEP_CAM);
// IT1-2015-0000151 DEL END
					sb.append(outMap.get(CHRG_TRGT_YM)); // 課金対象年月
					sb.append(JKKBatConst.S_SEP_CAM);
					sb.append(outMap.get(CRECARD_NO_AZKRI_ID)); // クレジットカード番号預りＩＤ
// IT1-2015-0000151 ADD START
					sb.append(JKKBatConst.S_SEP_CAM);
					sb.append(outMap.get(SHIKOSAKI_COMP_CD)); // 仕向先会社コード
// IT1-2015-0000151 ADD END
				
					out.write(sb.toString());
					out.newLine(); // 改行追加	
					out.flush();

				}
			} catch (IOException e) {
				// ファイル出力に失敗した場合、下記のログ出力する。
				throw new JBSbatBusinessException(JPCBatchMessageConstant.EKKB0140CE);
				
			} finally {
				out.close();
			}
		}
		
	}

	/**
	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
	
	/**
	 * カード預りID対象クレジットカード番号ファイル（Ｃｏ）取得処理
	 * @throws Exception 
	 */
	private List<Map<String, String>> getIspFile() throws Exception
	{
		// 2．3 ファイルを一行ずつ読み込みMapに格納し、ファイルのレコード分Listに格納する。
		List<Map<String, String>> fileList = new ArrayList<Map<String, String>>();
		BufferedReader br = null;
		
		try
		{
			br = new BufferedReader(new InputStreamReader(new FileInputStream(filePassCo), JKKBatConst.S_CHR_CODE));
			String data = br.readLine();				// 1行読込み

			while (data != null)
			{
				Map<String, String> fileMap = new HashMap<String, String>();
				String[] dataArray = data.split(JKKBatConst.S_SEP_CAM);
				fileMap.put(INPUT_MEMBER_NUMBER, JBSbatStringUtil.Rtrim(dataArray[3])); // 入力会員番号
				fileMap.put(INPUT_YK_KIGEN, JBSbatStringUtil.Rtrim(dataArray[4])); // 入力有効期限
				fileMap.put(CRECARD_ID, JBSbatStringUtil.Rtrim(dataArray[14])); // クレジットカードID
				fileMap.put(CRECARD_NO_AZKRI_ID, JBSbatStringUtil.Rtrim(dataArray[11])); // クレジットカード番号預りID
				
				fileList.add(fileMap);
				data = br.readLine();					// 1行読込み
			}
		}
		catch (FileNotFoundException fe)
		{
			// ファイルが存在しない場合は下記のログ出力する。
			throw new JBSbatBusinessException(JPCBatchMessageConstant.EKKB0020CE, 
				new String[]{filePassCo});
		}
		finally
		{
			if (br != null) {
				br.close();
			}
		}
		
		return fileList;
	}
	
	/**
	 * カード預りID対象クレジットカード番号ファイル（Ｃｏ）中間２取得処理
	 * @throws Exception
	 */
	private List<Map<String, String>> getMid2File() throws Exception
	{
		// 3．3 ファイルを一行ずつ読み込みMapに格納し、ファイルのレコード分Listに格納する。
		List<Map<String, String>> mid2List = new ArrayList<Map<String, String>>();
		BufferedReader br = null;

		try
		{
			br = new BufferedReader(new InputStreamReader(new FileInputStream(filePassMid2), JKKBatConst.S_CHR_CODE));
			String data = br.readLine();				// 1行読込み

			while (data != null)
			{
				Map<String, String> mid2Map = new HashMap<String, String>();
				String[] dataArray = data.split(JKKBatConst.S_SEP_CAM);
				mid2Map.put(CHRG_TRGT_YM, JBSbatStringUtil.Rtrim(dataArray[0])); // 課金対象年月
				mid2Map.put(SEIKY_KEI_NO, JBSbatStringUtil.Rtrim(dataArray[1])); // 請求契約番号
				mid2Map.put(CRECARD_NO, JBSbatStringUtil.Rtrim(dataArray[2])); // 請求契約番号
				mid2Map.put(SEIKY_WAY_NO_CRECARD, JBSbatStringUtil.Rtrim(dataArray[4])); // 請求方法番号
				mid2Map.put(SEIKY_NO, JBSbatStringUtil.Rtrim(dataArray[5])); // 請求番号
				mid2Map.put(SHIKOSAKI_COMP_CD, JBSbatStringUtil.Rtrim(dataArray[6])); // 仕向先会社コード
				mid2Map.put(CRECARD_ID, JBSbatStringUtil.Rtrim(dataArray[7])); // クレジットカードID
				
				mid2List.add(mid2Map);
				data = br.readLine();					// 1行読込み
			}
		}
		catch (FileNotFoundException fe)
		{
			// ファイルが存在しない場合は下記のログ出力する。
			throw new JBSbatBusinessException(JPCBatchMessageConstant.EKKB0020CE, 
				new String[]{filePassMid2});
		}
		finally
		{
			if (br != null) {
				br.close();
			}
		}
		return mid2List;
	}
	
	/**
	 * 読み込んだファイルをマージしたListの取得
	 * @throws Exception
	 */
	private List<Map<String, String>> getMergeList(List<Map<String, String>> ispList, List<Map<String, String>> mid2List)
	{
	
		List<Map<String, String>> keyList = new ArrayList<Map<String, String>>();
		List<Map<String, String>> nokeyList = new ArrayList<Map<String, String>>();
// IT2-2015-0000043 MOD START
//		for(Map<String, String> isp : ispList)
		for(Map<String, String> mid2 : mid2List)
// IT2-2015-0000043 MOD END
		{
// IT2-2015-0000043 MOD START
//			for(Map<String, String> mid2 : mid2List)
			for(Map<String, String> isp : ispList)
// IT2-2015-0000043 MOD END
			{
				// クレジットカード番号とクレジットカードIDによりマージ
				if(isp.get("INPUT_MEMBER_NUMBER").equals(mid2.get("CRECARD_NO")) 
						&& isp.get("CRECARD_ID").equals(mid2.get("CRECARD_ID")))
				{
					Map<String, String> mergeMap = new HashMap<String, String>();
					mergeMap.put(CRECARD_ID, JBSbatStringUtil.Rtrim(mid2.get("CRECARD_ID"))); // クレジットカード番号ID
					mergeMap.put(SHIKOSAKI_COMP_CD, JBSbatStringUtil.Rtrim(mid2.get("SHIKOSAKI_COMP_CD"))); // 仕向先会社コード
					mergeMap.put(CHRG_TRGT_YM, JBSbatStringUtil.Rtrim(mid2.get("CHRG_TRGT_YM"))); // 課金対象年月
					mergeMap.put(CRECARD_NO_AZKRI_ID, JBSbatStringUtil.Rtrim(isp.get("CRECARD_NO_AZKRI_ID"))); // クレジットカード番号預りID
					
					// 更新キー項目あればkeyListに、なければnokeyListに格納する
					if(checkUpdateKey(mergeMap))
					{
						keyList.add(mergeMap);
					}
					else
					{
						nokeyList.add(mergeMap);
					}
					break;
				}
			}
		}
		// 更新キー項目ありのリストに更新キー項目なしのリストを追加
		keyList.addAll(nokeyList);
		
		return keyList;

	}
	
	/**
	 * <p>
	 * 更新キー項目ありなしチェック
	 * </p>
	 * 更新キー項目があれば真、なければ偽
	 * @param fileMap
	 * @return
	 */
	private boolean checkUpdateKey(Map<String, String> fileMap) {
		if(fileMap.get(JBSbatKKIFM676.CHRG_TRGT_YM) != null && !fileMap.get(JBSbatKKIFM676.CHRG_TRGT_YM).isEmpty()
				&& fileMap.get(JBSbatKKIFM676.CRECARD_ID) != null && !fileMap.get(JBSbatKKIFM676.CRECARD_ID).isEmpty())
		{
			return true;
		}
		return false;
	}
}
