/*********************************************************************
* All Rights reserved,Copyright (c) K-Opticom
**********************************************************************
*＜プログラム内容＞
*   システム名      ：eo顧客基幹システム
*   モジュール名    ：物流管理システム
*   ソースファイル名：DKW00401SFLogic.java
*   作成者          ：富士通
*   日付            ：2011年08月09日
*＜機能概要＞
*   Ver読込画面を処理するロジッククラスです。
*＜修正履歴＞
*   バージョン  修正日       修正者      修正内容
*   v1.00.00    2011/08/09   FJ          新規作成
*
**********************************************************************/
package eo.web.webview.DKW02804SF;

import static com.fujitsu.futurity.web.x31.X31SWebLog.DEBUG_LOG;
import static eo.common.constant.JDKStrConst.*;
import static eo.common.constant.JPCOnlineMessageConstant.EKB0830_TW;
import static eo.common.constant.JPCOnlineMessageConstant.EKB0010_TW;
import static eo.common.constant.JPCOnlineMessageConstant.EKB0040_TW;
import static eo.common.constant.JPCOnlineMessageConstant.EKB0940_KW;
import static eo.common.constant.JPCOnlineMessageConstant.EKB0640_KW;
import static eo.common.constant.JPCOnlineMessageConstant.EKB4590_KW;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.fujitsu.futurity.web.x31.X31CWebConst;
import com.fujitsu.futurity.web.x31.X31SDataBeanAccess;

import eo.common.constant.JDKStrConst;
import eo.common.util.JDKCommonUtil;
import eo.web.webview.JCCWebBusinessLogic;
import eo.web.webview.CommonInfoCF.CommonInfoCFConst;
import eo.web.webview.DKW02801SF.DKW02801SFConst;
import eo.web.webview.common.JCCScreenConst;
import eo.web.webview.common.JCCWebCommon;
import eo.web.webview.common.JDKWebCommon;


/**
 * Ver登録画面を処理するロジッククラスです。
 * @author 富士通
 */
public class DKW02804SFLogic extends JCCWebBusinessLogic
{
	/** シリアル番号 */
	private static final long serialVersionUID = 1L;

	/** メッセージ(項目数不一致) */
	private static final String MSG_UNMATCH_COLUMN = "項目数不一致";
	/** メッセージ(項目数) */
	private static final String MSG_COLUMN_COUNT = "項目数";

	/** 最大読込可能件数 */
	private static final int MAX_READABLE_LINES = 2000;
	/** カラム数 */
	private static final int COLUMN_COUNT = 2;
	
	/** セッションからファイルを取得する際のキー */
	private static final String SESSION_KEY_FILE = "fileKey";

	/** セッションから読込ファイル情報リストを取得する際のキー */
	private static final String SESSION_KEY_READ_FILE_INFO = "readFileInfoKey";
	

	/**
	 * 初期化処理を行います。
	 * @return 処理実行結果
	 */
	public boolean init()
	{
		return true;
	}

	/**
	 * 読込ボタンを処理します。
	 * @author 富士通
	 * @return 成否
	 * @throws Exception 例外
	 */
	public boolean upload() throws Exception
	{
		ArrayList<HashMap<String, Object>>  fileInfoList  = JCCWebCommon.getFileInfoArray(this);
		
		if (fileInfoList.size() == 0)
		{
			setMessage(EKB4590_KW, "ファイル");
			return false;
		}
		
		// 共通のチェック処理の呼び出し
		if (!JDKWebCommon.isCommonFileUploaded(fileInfoList, this))
		{
			return false;
		}
		
		String file = getFileAsString(fileInfoList);

		if (!isValidColumns(file))
		{
			return false;
		}

		saveFileToSession(file);
		
		setNextScreen(JCCScreenConst.SCREEN_ID_CCW00105, JCCScreenConst.SCREEN_NAME_CCW00105);
		return true;
	}

	/**
	 * ファイルの内容を文字列で取得します。
	 * @author 富士通
	 * @param fileInfoList
	 * @return ファイル内容
	 */
	@SuppressWarnings("unchecked")
	private String getFileAsString(ArrayList<HashMap<String, Object>>  fileInfoList)
	{
		HashMap fileInfoMap = fileInfoList.get(0);
		String renbanKey = fileInfoMap.get(SESSION_KEY_FILE).toString();

		byte[] fileByte = JCCWebCommon.getFile(this, renbanKey);
		
		return new String(fileByte);
	}

	/**
	 * ファイルの行毎に期待される項目数をチェックします。
	 * @author 富士通
	 * @param file 精査するファイル
	 * @return true:エラーなし false:エラーあり
	 */
	private boolean isValidColumns(String file) throws Exception
	{
		int index = 0;
		int lineNum = 0;
		String[] lines = file.split(JDKStrConst.LINE_SEPARATOR);
		ArrayList<Object> readList = new ArrayList<Object>();
		
		if (lines.length > MAX_READABLE_LINES) 
		{
			setMessage(EKB0640_KW, "指定されたファイル", "最大読込可能件数");
			return false;
		}
		
		boolean retFlg = true;
		for (String line : lines)
		{
			if (!isValidColumn(line, ++index))
			{
				retFlg = false;
			}
			
			// 重複チェックの呼び出し
			if (!isRepeatedColumn(line, ++lineNum, readList))
			{
				retFlg = false;
			}
		}
		if (!retFlg)
		{
			return false;
		}
		// エラーがなかった場合だけセッションにセット
		HashMap<String,Object> paramMap = new HashMap<String,Object>();
		paramMap.put("readList", readList);
		JCCWebCommon.setScreenInfo(this, SESSION_KEY_READ_FILE_INFO, paramMap);
		
		return true;
	}

	/**
	 * 指定の文字列が指定の項目数ではない場合、メッセージを設定します。
	 * @author 富士通
	 * @param line 精査する文字列
	 * @param index lineの行数
	 * @return true:エラーなし false:エラーあり
	 */
	private boolean isValidColumn(final String line, int index)
	{
		
		String [] columns = JDKCommonUtil.splitAnycase(line, COMMA);
		
		for (int i=0; i<columns.length; i++)
		{
			columns[i] = columns[i].replaceAll(DOUBLE_QUAT, "");
		}
		
		if (columns == null
				|| columns.length != COLUMN_COUNT)
		{
			setMessage(EKB0830_TW, Integer.toString(index), 
									MSG_COLUMN_COUNT,
									MSG_UNMATCH_COLUMN);
			return false;
		}
		
		if (columns[0].equals(""))
		{
			setMessage(EKB0010_TW, "型番号"); 
			return false;
		}
		
		if (columns[0].length() > 20)
		{
			setMessage(EKB0040_TW, "型番号", "1", "20"); 
			return false;
		}
		
		if (columns[1].equals(""))
		{
			setMessage(EKB0010_TW, "製造番号"); 
			return false;
		}
		
		if (columns[1].length() > 20)
		{
			setMessage(EKB0040_TW, "製造番号", "1", "20"); 
			return false;
		}

		return true;
	}

	/**
	 * ファイル情報をセッションに保存します。
	 * @author 富士通
	 * @param file ファイル内容
	 * @throws Exception 例外発生時
	 */
	@SuppressWarnings("unchecked")
	private void saveFileToSession(String file) throws Exception
	{
		HashMap paramMap = new HashMap();
		List<String> modelList = new ArrayList<String>();
		List<String> seizoList = new ArrayList<String>();
		
		String[] lines = file.split(JDKStrConst.LINE_SEPARATOR);
		
		for (String line : lines)
		{
			String [] columns = JDKCommonUtil.splitAnycase(line, COMMA);

			modelList.add(columns[0]);
			seizoList.add(columns[1]);
		
		}

		paramMap.put(DKW02801SFConst.SEARCH_MODEL_LIST, modelList);
		paramMap.put(DKW02801SFConst.SEARCH_SEIZO_LIST, seizoList);

		String parentScreenId = JCCWebCommon.getScreenId(this); 
		JCCWebCommon.setScreenInfo(this, parentScreenId, paramMap);
	}
	
	/**
	 * メッセージを設定します。
	 * @author 富士通
	 * @param messageId メッセージＩＤ
	 * @param replacements 置換文字列
	 */
	private void setMessage(String messageId, String...replacements)
	{
		JCCWebCommon.setMessageInfo(this, messageId, replacements);
	}

	/**
	 * 画面遷移先を設定します。
	 * @param nextScreenId 遷移先画面ＩＤ
	 * @param nextScreenName 遷移先画面名
	 */
	private void setNextScreen(String nextScreenId, String nextScreenName) 
	{
		X31SDataBeanAccess  commoninfoBean = super.getCommonInfoBean();
	
		commoninfoBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_ID, X31CWebConst.DATABEAN_SET_VALUE, nextScreenId);
		commoninfoBean.sendMessageString(CommonInfoCFConst.NEXT_SCREEN_NAME, X31CWebConst.DATABEAN_SET_VALUE, nextScreenName);

		DEBUG_LOG.debug(String.format("遷移先 CD：%s NM：%s", nextScreenId, nextScreenName));
	}

	/**
	 * ファイル読込したデータに重複があれば、メッセージを設定します。
	 * @author 富士通
	 * @param line 精査する文字列
	 * @param index lineの行数
	 * @param readList 読込済みのファイル情報
	 * @return true:エラーなし false:エラーあり
	 */
	private boolean isRepeatedColumn(final String line, int index, ArrayList<Object> readList)
	{
		String [] columns = JDKCommonUtil.splitAnycase(line, COMMA);

		for (int i=0; i<columns.length; i++)
		{
			columns[i] = columns[i].replaceAll(DOUBLE_QUAT, "");
		}

		if (readList.size() == 0)
		{
			// 1件目は比較対象が存在しない為、無条件にリストにセット
			readList.add(columns);
			return true;
		}
		else
		{
			// 突き合わせチェック
			for (int i = 0; i < readList.size(); i++)
			{
				String readData[] = new String[2];
				readData = (String[]) readList.get(i);
				if (columns[0].equals(readData[0]) && columns[1].equals(readData[1]))
				{
					// 重複あり
					setMessage(EKB0940_KW, "製造番号[" + columns[1] + "]", "重複", String.valueOf(index)); 
					return false;
				}
				else
				{
					continue;
				}
			}
			// 重複なし
			readList.add(columns);
			return true;
		}
	}
	

}
