/*********************************************************************
*  All Rights reserved,Copyright (c) K-Opticom					 *
**********************************************************************
*＜プログラム内容＞
*	システム名			：eo顧客基幹システム
*	モジュール名		：JBSbatSCKnsiSvcOdrSrinf
*	ソースファイル名	：JBSbatSCKnsiSvcOdrSrinf.java
*	作成者				：富士通　
*	作成日				：2011年07月08日
*＜機能概要＞
*　サービスオーダ送受信情報監視部品です。
*＜修正履歴＞
*	バージョン	修正日		修正者		修正内容
*	v1.00.00	2011/07/08   富士通		新規作成
*********************************************************************/
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.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import eo.business.common.JBSbatBusinessService;
import eo.framework.item.JBSbatCommonItem;
import eo.framework.item.JBSbatServiceInterfaceMap;
import eo.framework.item.JBSbatOutputItem;
import eo.framework.application.JBSbatBusinessException;

/**
* (クラスの機能概要) <p>
*<BR>
* @author 富士通
*/
public class JBSbatSCKnsiSvcOdrSrinf extends JBSbatBusinessService
{
	/**▼▼▼▼▼▼ツールから生成した宣言です 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成した宣言です 終了▲▲▲▲▲▲*/
	
	/** アラーム出力なし */
	private static final int ALM_NONE = 0;
	/** メジャーアラーム */
	private static final int ALM_MAJOR = 127;
	/** マイナーアラーム */
	private static final int ALM_MINOR = 8;
	
	/** アラーム出力定義パラメタ情報ファイルパス */
	private String fileNamePrm = "";
	/** 応答結果監視処理済日時情報ファイルパス */
	private String fileNameUpdDtm = "";
	
	/** サービスオーダ送受信 */
	private String updDtmSvc = "";
	/** UQオーダ送受信 */
	private String updDtmUq = "";
	/** SPOTオーダ送受信 */
	private String updDtmSpot = "";
	
	/** アラーム識別 */
	/** 0:アラームなし 1:アラームあり */
	//private int alarmExecuted = 0; 
	
	/** パラメタ格納用リスト */
	private ArrayList<HashMap<String, String>> prmFile = new ArrayList<HashMap<String, String>>();

	/**
	 * 初期処理
	 * @param JBSbatCommonItem commonItem　バッチ共通パラメータ電文
	 * @throws Exception
	 */
	public void initial(JBSbatCommonItem commonItem) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの初期処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した初期化のソースです 開始▼▼▼▼▼▼*/
		// 共通パラメタを設定します
		super.setCommonInfo(commonItem);
		/**▲▲▲▲▲▲ツールから生成した初期化のソースです 終了▲▲▲▲▲▲*/
		
		// 「FREE」パラメタからファイルパスを取得する
		String[] free_item_ary = commonItem.getFreeItem().split(";");
		fileNamePrm = free_item_ary[0];
		fileNameUpdDtm = free_item_ary[1];
		
		// アラーム出力定義パラメタ情報ファイルの読み込み
		readPrmFile();
		
		// 応答結果監視処理済日時情報ファイルの読み込み
		readUpdDtmFile();
		
	/**▲▲▲▲▲▲業務サービスの初期処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 主処理
	 * @param inMap　入力電文
	 * @return JBSbatOutputItem　出力情報
	 * @throws Exception
	 */
	public JBSbatOutputItem execute(JBSbatServiceInterfaceMap inMap) throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの主処理を記述してください。▼▼▼▼▼▼*/
		
		String msgCode = "";
		String svcodrName = "";
		
		// パラメタ情報を調べてアラーム出力を判定する
		int kindOfAlarm = getKindOfAlarm(inMap);
		if (ALM_NONE == kindOfAlarm)
		{
			return null;
		}
		
		switch (getKindOfAlarm(inMap))
		{
			case ALM_MINOR:  // マイナーアラーム
				msgCode = "ESCB0230CW";
				break;
				
			case ALM_MAJOR:  // メジャーアラーム
				msgCode = "ESCB0240CE";
				break;
				
			case ALM_NONE:  // アラーム出力なし
				
			default:
				return null;
			
		}
		
		// オーダの種別を判定する
		// サービスオーダ送受信
		if ("1".equals(inMap.getString("SORT1")))
		{
			if ("24".equals(inMap.getString("SVC_ORDER_CD")))  // 24：緊急通報
			{
				svcodrName = "ECS-SOD";
			}
			else
			{
				svcodrName = "IP-SOD";
			}
			updDtmSvc = inMap.getString("SOD_RSLT_ADD_DTM");
		}
		// UQオーダ送受信
		else if ("2".equals(inMap.getString("SORT1")))
		{
			svcodrName = "UQ-SOD";
			updDtmUq = inMap.getString("SOD_RSLT_ADD_DTM");
		}
		// SPOTオーダ送受信
		else if ("3".equals(inMap.getString("SORT1")))
		{
			svcodrName = "SPOT-SOD";
			updDtmSpot = inMap.getString("SOD_RSLT_ADD_DTM");
		}
		
		// Syslogにアラーム出力
		super.logPrint.printBusinessErrorLog(msgCode, new String[]{
				svcodrName,
				nullToString(inMap.getString("SVC_ORDER_CD")),
				nullToString(inMap.getString("YOKYU_SBT_CD")) + 
				" SEQ=" + nullToString(inMap.getString("SRINF_KANRI_NO")) + 
				" ID=" + nullToString(inMap.getString("SVC_KEI_NO")) + 
				" RC=" + nullToString(inMap.getString("SOD_TRAN_RSLT_DTAIL_CD"))
		});
		//throw new JBSbatBusinessError(msgCode);
		
		//alarmExecuted = 1;
		
		return null;
	/**▲▲▲▲▲▲業務サービスの主処理を記述してください。▲▲▲▲▲▲*/
	}

	/**
	 * 業務サービス終了処理
	 * @throws Exception
	 */
	public void terminal() throws Exception
	{
	/**▼▼▼▼▼▼業務サービスの終了処理を記述してください。▼▼▼▼▼▼*/
		/**▼▼▼▼▼▼ツールから生成した終了処理のソースです 開始▼▼▼▼▼▼*/
		/**▲▲▲▲▲▲ツールから生成した終了処理のソースです 終了▲▲▲▲▲▲*/
		
		// 
		// 応答結果監視処理済日時情報ファイルの書き込み
		writeUpdDtmFile();
		
		// アラーム出力があった場合はエラーをスローして終了
//		if ( 1 == alarmExecuted ) {
//			throw new JBSbatBusinessError();
//		}
		
	/**▲▲▲▲▲▲業務サービスの終了処理を記述してください。▲▲▲▲▲▲*/
	}

	/**▼▼▼▼▼▼ツールから生成したメソッドです 開始▼▼▼▼▼▼*/
	/**▲▲▲▲▲▲ツールから生成したメソッドです 終了▲▲▲▲▲▲*/
	
	
	/**
	 * アラーム出力の種類の判別を行います。<br>
	 * <br>
	 * @param inMap 入力電文
	 * @return  int アラーム出力の種別
	 * @throws Exception
	 */
	private int getKindOfAlarm(JBSbatServiceInterfaceMap inMap) throws Exception
	{
		Iterator<?> iterator = prmFile.iterator();
		
		// パラメタ情報に合致しなければメジャーアラームなので、予めメジャーアラームを設定しておく
		int iAlarm = ALM_MAJOR;
		
		while (iterator.hasNext())
		{
			HashMap<String, String> prmLine = (HashMap<String, String>)iterator.next();
			// サービスオーダコードの比較
			if (comparePrmData(prmLine.get("SVC_ORDER_CD"), nullToString(inMap.getString("SVC_ORDER_CD"))))
			{
				// 処理結果詳細コードの比較
				if (comparePrmData(prmLine.get("SOD_TRAN_RSLT_DTAIL_CD"), nullToString(inMap.getString("SOD_TRAN_RSLT_DTAIL_CD"))))
				{
					// エラーレベル「N」はアラーム出力しない
					if (prmLine.get("ERR_LEVEL").equals("N"))
					{
						iAlarm = ALM_NONE;
						break;
						// エラーレベル「A」はマイナーアラーム
					}
					else if (prmLine.get("ERR_LEVEL").equals("A"))
					{
						iAlarm = ALM_MINOR;
						break;
					}
					else
					{
						super.logPrint.printDebugLog("アラーム出力定義パラメタ情報のエラーレベルに予期しない値を検出");
						throw new JBSbatBusinessException("ESCB0250CE", new String[] {prmLine.get("ERR_LEVEL")});
					}
				}
			}
		}
		
		return iAlarm;
	}
	
	/**
	 * アラーム出力定義パラメタ情報ファイルの読み込みを行います。
	 * @throws Exception
	 */
	private void readPrmFile() throws Exception
	{
		FileReader fr = null;
		BufferedReader br = null;
		try
		{
			// Text指定ファイル読込み
			File file = new File(fileNamePrm);
			fr = new FileReader(file);
			br = new BufferedReader(fr);
			
			while (br.ready())
			{
				String lineData = br.readLine();
				
				// 空白行は処理しない
				if (0 < lineData.length())
				{
					// １文字目が空白以外は注釈行なので飛ばす
					if (" ".equals(lineData.substring(0, 1)))
					{
								HashMap<String, String> lineHhmp = new HashMap<String, String>(2);
						
						lineHhmp.put("ERR_LEVEL", lineData.substring(1, 2));
						lineHhmp.put("SVC_ORDER_CD", lineData.substring(3, 5));
						lineHhmp.put("SOD_TRAN_RSLT_DTAIL_CD", lineData.substring(6));
						
						prmFile.add(lineHhmp);
					}
				}
			}
		}
		catch(IOException e)
		{
			super.logPrint.printDebugLog("アラーム出力定義パラメタ情報の読み込み失敗");
			throw new JBSbatBusinessException("ESCB0260CE", new String[] {fileNamePrm});
		}
		finally
		{
			if(null != fr)
			{
				fr.close();
			}
			if(null != br)
			{
				br.close();
			}
		}
	}
	
	/**
	 * 応答結果監視処理済日時情報ファイルの読み込みを行います。
	 * @throws Exception
	 */
	private void readUpdDtmFile() throws Exception
	{
		FileReader fr = null;
		BufferedReader br = null;
		try
		{
			// Text指定ファイル読込み
			File file = new File(fileNameUpdDtm);
			fr = new FileReader(file);
			br = new BufferedReader(fr);
			
			String lineData = br.readLine();
			String[] lineDataAry = lineData.split(",");
			
			updDtmSvc = lineDataAry[0];
			updDtmUq = lineDataAry[1];
			updDtmSpot = lineDataAry[2];
		}
		catch(IOException e)
		{
			super.logPrint.printDebugLog("応答結果監視処理済日時情報の読み込み失敗");
			throw new JBSbatBusinessException("ESCB0260CE", new String[] {fileNameUpdDtm});
		}
		finally
		{
			if(null != fr)
			{
				fr.close();
			}
			if(null != br)
			{
				br.close();
			}
		}
	}
	
	/**
	 * 応答結果監視処理済日時情報ファイルの書き込みを行います。
	 * @throws JBSbatBusinessException
	 */
	private void writeUpdDtmFile() throws JBSbatBusinessException
	{
		String str_data = updDtmSvc + "," + updDtmUq + "," + updDtmSpot;
		
		try
		{
			FileWriter fr = new FileWriter(fileNameUpdDtm);
			BufferedWriter bw = new BufferedWriter(fr);
			PrintWriter writer  = new PrintWriter(bw);
			writer.println(str_data);
			writer.close();
		}
		catch (IOException e)
		{
			super.logPrint.printDebugLog("応答結果監視処理済日時情報の出力失敗");
			throw new JBSbatBusinessException("ESCB0270CE", new String[] {fileNameUpdDtm});
		}
	}
	
	/**
	 * パラメータ情報と入力電文のデータ比較を行います。
	 * @param prmVal パラメータ情報の値
	 * @param inVal 入力電文の値
	 * @return boolean true：マッチ false：マッチしない
	 */
	private boolean comparePrmData(String prmVal, String inVal)
	{
		String compareVal = "";
		int i = 0;
		
		// 比較対象データの桁数がパラメタの桁数に満たない場合は、後方をスペースで埋めて桁数を揃える
		if (prmVal.length() > inVal.length())
		{
			StringBuffer add_space = new StringBuffer();
			for (i = inVal.length(); i < prmVal.length(); i++)
			{
				add_space.append(" ");
			}
			compareVal = inVal + add_space.toString();
		}
		else
		{
			compareVal = inVal;
		}
		
		// 1文字ずつ比較する
		boolean matched = true;
		for (i = 0; i < prmVal.length(); i++)
		{
			if (!prmVal.substring(i, i + 1).equals("*"))
			{
				if (!prmVal.substring(i, i + 1).equals(compareVal.substring(i, i + 1)))
				{
					matched = false;
					break;
				}
			}
		}
		
		return matched;
	}
	
	/**
	 * nullを空文字に変換します。
	 * @param inVal 対象データ
	 * @return String 引数がnullの場合は空文字、それ以外は引数そのまま返す
	 */
	private String nullToString(String inVal)
	{
		if (null == inVal)
		{
			return "";
		}
		else
		{
			return inVal;
		}
	}
}
