/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatKKShohinkHskkjhRnk
*	ソースファイル名	：JBSbatKKShohinkHskkjhRnk.java
*	作成者				：富士通　
*	作成日				：2012年04月21日
*＜機能概要＞
*　商品券発送結果情報作成部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v3.00.00	2012/04/27  FJ)上田		新規作成
*	v5.00.00	2013/07/25  FJ)井熊		【IT1-2013-0001438】守口印刷受信ファイル名変更対応
*	v5.00.01	2013/09/04  FJ)三宅		【OM-2013-0001376 】件数ファイル出力内容不正対応
*********************************************************************/
package eo.business.service;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import eo.business.common.JBSbatBusinessService;
import eo.business.common.JKKBatCommon;
import eo.business.common.JKKBatConst;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.file.JBSbatInputFileUtil;
import eo.framework.file.JBSbatOutputFileUtil;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatKKShohinkHskkjhRnk extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/
	
	/** ファイル連携先ディレクトリ定義キー */
	private static final String CR_FILE_DIR_KEY = "CR_TWS_RK_FILE_DIR";

	/** セミコロン */
	private static final String DELIM = JKKBatConst.S_PARAM_DELIM;

	/** 文字コード */
	private static final String SJIS  = JKKBatConst.SJIS;

	/** 半角スラッシュ */
	private static final String SLASH  = JKKBatConst.S_HALF_SLASH;

	/** 改行コード */
	private static final String CRLF  = "CR+LF";
	
	/** 件数ファイル括り文字 */
	private static final String SCOPE  = "\"";

	/** ファイル連携先ディレクトリ(フルパス) */
	private String crFileDir = null;
	
// v5.00.01 2013.09.04 DEL START
//	/** CASEファイル出力件数 */
//	private int outmapCnt = 0;
// v5.00.01 2013.09.04 DEL END
	
	/** CASEファイル */
	private String caseFile = null;
	
	/** CASE件数ファイル名 */
	private String cntFileNm = null;

	/** フラグファイル名 */
	private String flgFileNm = null;

	// ◆◆ IT1-2013-0001438 add ◆◆
	/** インプットファイル名 */
	private String inputFileNm = null;
	// ◆◆ IT1-2013-0001438 end ◆◆

// v5.00.01 2013.09.04 ADD START
	/** デフォルト文字コード */
	public static final String DEFAULT_ENCODE = "MS932";
	/** 改行コード変換文字の囲い文字 */
	private static final char KAKOI = '%';
	/** 終端文字 */
	private static final String END = "[END]";
	/** コメント文字 */
	private static final String COMMENT = "#";
	/** 改行コード変換文字を取得するキー */
	static final String KEY_KAIGYO_CD_HENKAN_MOJI = "KEY_KAIGYO_CD_HENKAN_MOJI";
	/** 変換処理後のファイルを取得するキー */
	static final String KEY_HENKANGO_FILE = "KEY_HENKANGO_FILE";
	/** 有効データ件数を取得するキー */
	static final String KEY_COUNT = "KEY_COUNT";
	/** 改行コード */
	public static final String KAIGYO_CD = "\r\n";

// v5.00.01 2013.09.04 ADD END
	
	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメータを設定します
		super.setCommonInfo(commonItem);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
		
		// アプリケーションプロパティファイルからファイル連携先ディレクトリを取得
		this.crFileDir = JKKBatCommon.getApplicationConst(CR_FILE_DIR_KEY);
		super.logPrint.printDebugLog("ファイル連携先ディレクトリ:" + this.crFileDir);
		
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		// フリー項目より、対応履歴に連携するファイル名を取得
		String[] fileNames = super.freeItem.split(DELIM);
		// ◆◆ IT1-2013-0001438 mod ◆◆
//		if (fileNames.length == 3)
		if (fileNames.length == 4)
		// ◆◆ IT1-2013-0001438 mod ◆◆
		{
			this.caseFile = fileNames[0];
			this.cntFileNm = fileNames[1];
			this.flgFileNm = fileNames[2];
			// ◆◆ IT1-2013-0001438 add ◆◆
			this.inputFileNm = fileNames[3];
			// ◆◆ IT1-2013-0001438 end ◆◆
		}
		
// v5.00.01 2013.09.04 DEL START（outmapCntを使わず件数を設定するため、コメントアウト）
//		outmapCnt++;
// v5.00.01 2013.09.04 DEL END
		
		return null;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
		// ◆◆ IT1-2013-0001438 add ◆◆
//		String fileName = this.caseFile;
		String fileName = this.inputFileNm;
		// ◆◆ IT1-2013-0001438 end ◆◆

// v5.00.01 2013.09.04 DEL START
		if(fileName == null)
		{
			// fileNameがnullの場合、以降の処理を行わない
			return;
		}
// v5.00.01 2013.09.04 DEL END
		// コピー元ファイルのデータ読み込み
		JBSbatInputFileUtil targetFile = new JBSbatInputFileUtil(fileName);
		super.logPrint.printDebugLog("処理対象ファイル:" + fileName);
		ArrayList<String> inArr = new ArrayList<String>();
		targetFile.setEncode(SJIS);
		targetFile.createReader();
		while (targetFile.ready())
		{
			// ファイルレコード取得
			inArr.add(targetFile.readLine());
		}
		targetFile.close();
		
// v5.00.01 2013.09.04 ADD START
		File csvFile = new File(fileName);
		Map<String, Object> tmpFileMap = chgToOneRowForCsv(commonItem, csvFile);
		int dataCount = ((Integer)tmpFileMap.get(KEY_COUNT)).intValue();
// v5.00.01 2013.09.04 ADD END

		// ◆◆ IT1-2013-0001438 add ◆◆
		String caseFileName = this.caseFile;
		// ◆◆ IT1-2013-0001438 end ◆◆

		// コピー先ファイルの設定

		// ◆◆ IT1-2013-0001438 del ◆◆
		// シェルからはファイル名部分のみを渡すように修正
//		String[] filePath = caseFileName.split(SLASH);
//		String file = filePath[filePath.length - 1];
		// ◆◆ IT1-2013-0001438 end ◆◆
		
		StringBuffer casefile = new StringBuffer();
		casefile.append(this.crFileDir);
		casefile.append(SLASH);
		// ◆◆ IT1-2013-0001438 add ◆◆
//		casefile.append(file);
		casefile.append(caseFileName);
		// ◆◆ IT1-2013-0001438 end ◆◆
		JBSbatOutputFileUtil sendFile = new JBSbatOutputFileUtil(casefile.toString());
		sendFile.setEncode(JKKBatConst.SJIS);
		sendFile.setLine(CRLF);
		sendFile.createWriter();
		for (String line : inArr) 
		{
			// データをファイルに出力
			sendFile.write(line);
		}
		sendFile.close();
		
		// 件数ファイルを作成し、処理件数を出力
		String createCntFilePath = null;
		
		StringBuffer cntfile = new StringBuffer();
		cntfile.append(this.crFileDir);
		cntfile.append(SLASH);
		cntfile.append(this.cntFileNm);
		createCntFilePath = cntfile.toString();
		
		JBSbatOutputFileUtil cntFile = new JBSbatOutputFileUtil(createCntFilePath);
		cntFile.setEncode(SJIS);
		cntFile.setLine(CRLF);
		cntFile.createWriter();
		StringBuffer count = new StringBuffer();
		count.append(SCOPE);
// v5.00.01 2013.09.04 ADD START
//		count.append(String.valueOf(this.outmapCnt));
		count.append(String.valueOf(dataCount));
// v5.00.01 2013.09.04 ADD END
		count.append(SCOPE);
		cntFile.write(count.toString());
		cntFile.close();
		
		// フラグファイルを作成
		String flgFilePath = null;

		StringBuffer flgfile = new StringBuffer();
		flgfile.append(this.crFileDir);
		flgfile.append(SLASH);
		flgfile.append(this.flgFileNm);
		flgFilePath = flgfile.toString();

		JBSbatOutputFileUtil flgFile = new JBSbatOutputFileUtil(flgFilePath);
		flgFile.setEncode(SJIS);
		flgFile.setLine(CRLF);
		flgFile.createWriter();
		flgFile.close();

	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

// v5.00.01 2013.09.04 ADD START
	/**
	 * CSV1レコード1行化<P>
	 * ダブルクォートに囲まれた項目内に改行があるCSVファイルをの1レコードを
	 * 1行に変換して一時ファイルに出力する。
	 * 改行コードは別の文字に変換する。
	 * @param commonItem 共通情報
	 * @param file 変換対象ファイル
	 * @return 変換情報のMap
	 * 				キー						内容
	 * 				KEY_KAIGYO_CD_HENKAN_MOJI	改行コード変換文字列(String)
	 * 				KEY_COUNT					件数(Integer)
	 * @throws IOException 例外
	 */
	static Map<String, Object> chgToOneRowForCsv(JBSbatCommonItem commonItem, File file) throws IOException
	{
		Map<String, Object> resMap = new HashMap<String, Object>();

		int dataCount = 0;			// データ件数

		BufferedReader br = null;

		try
		{
			// 読込みファイル
			br = new BufferedReader(new InputStreamReader(new FileInputStream(file), DEFAULT_ENCODE));

			// ファイル内容を全行読込

			String data = br.readLine();				// 1行読込み
			StringBuilder sb = new StringBuilder();		// 読込みファイル内容保持用

			while (data != null)
			{
				sb.append(data);
				sb.append(KAIGYO_CD);		// 改行コードLFを付加

				data = br.readLine();					// 1行読込み
			}

			// 改行コード変換文字設定
			int index = 0;
			int i = 0;
			String chgWordLF = "";						// 改行コード変換文字
			while (index > -1)
			{
				// 変換に使用するための文字が存在した場合は別の文字を設定する
				chgWordLF = KAKOI + "LF" + i++ + KAKOI;
				index = sb.indexOf(chgWordLF);
			}

			// 全内容を1行化
			String fileContents = sb.toString().replaceAll(KAIGYO_CD, chgWordLF);

			StringBuilder buff = new StringBuilder();

			int quoteCount = 0;
			for (int j = 0; j < fileContents.length(); j++)
			{
				char chr = fileContents.charAt(j);
				buff.append(chr);

				if (chr == '\"')
				{
					quoteCount++;
				}

				if (chr == KAKOI)
				{
					if (quoteCount % 2 == 0)
					{
						// "の出現回数が偶数の場合
						String tmp = buff.toString();
						if (tmp.endsWith(chgWordLF))
						{
							// 改行変換文字で終わっている場合
							// 1行出力
							buff.delete(buff.length() - chgWordLF.length(), buff.length());

							String work = buff.toString().trim();
							if (work.startsWith(END))
							{
								// 先頭が終端文字の場合は以降の処理を行わない
								break;
							}
							if (!("".equals(work)) && !(work.startsWith(COMMENT)))
							{
								// 空白行でなくコメント行でない場合、ファイル出力
								dataCount++;
							}

							buff.delete(0, buff.length());	// クリア
							quoteCount = 0;
						}
					}
				}
			}

			resMap.put(KEY_KAIGYO_CD_HENKAN_MOJI, chgWordLF);
			resMap.put(KEY_COUNT, dataCount);

			return resMap;

		}
		catch (IOException ioe)
		{
			commonItem.getLogPrint().printDebugLog(ioe.getMessage());
			throw ioe;
		}
		finally
		{
			// 読込みファイルクローズ
			if (br != null)
			{
				try
				{
					br.close();
				}
				catch (IOException ioe)
				{
					commonItem.getLogPrint().printDebugLog("br close error");
				}
			}
		}
	}
// v5.00.01 2013.09.04 ADD END

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
}
