/*
 * COMMBiz.java	2011. 03. 17
 *
 * Copyright 2011 FUJITSU KOREA LTD. All rights reserved.
 * FUJITSU KOREA LTD PROPRIETARY/CONFIDENTIAL. 
 * Use is subject to license terms.
 */

package biz.comm;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JOptionPane;

import org.apache.log4j.Logger;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import kr.fujitsu.com.ffw.daemon.core.DaemonConfigLocator;
import kr.fujitsu.com.ffw.daemon.core.config.repository.telegram.Field;
import kr.fujitsu.com.ffw.daemon.core.config.repository.telegram.MessageForm;
import kr.fujitsu.com.ffw.daemon.core.config.repository.telegram.TelegramUtil;
import kr.fujitsu.com.ffw.util.StringUtil;


/** 
 * COMMBiz
 *  
 * @created  on 1.0,  11/03/17
 * @created  by oki(FUJITSU KOREA LTD.) 
 *  
 * @modified on 
 * @modified by 
 * @caused   by  
 */ 
public class COMMBiz {
	private static Logger logger = Logger.getLogger(COMMBiz.class);
	
	public static int CM_LENS = 59;			//50에서 변경함.
	public static String CM_HEADER    = "MASTER_CM_HEADER";
										 
	//MSG_TYPE	(마스터 download 용 메시지 타입 추가 ) 
	public static int MASTER  = 8;
	public static int ERR     	= 99;
	public static int SYSINQ  = 6;
	                 
	//MASTERDATA   
	public static String XML_MASTERDATA_SQL       = "nhsmaster-sql";
	public static String XML_SYSINQ_SQL       = "nhssysinq-sql";
		
	public static String TB_DELIMITER = "#~";
	public static String ROW_DELIMITER = "#~";
	public static String FIELD_DELIMITER = "|";
	
	//마스터 down시 일자 관리 
	public static int PARI_DOWNDATE = 3;
	public static int BRK_DOWNDATE = 3;	// ITEM은 900 일
	public static int SL_DOWNDATE = 1;
	
	
	public static String TB_UPD_POS_DEPLOY_MNG_0  = "UPD_POS_DEPLOY_MNG_0"; //배신결과POS전송 플래그세팅
	public static String TB_UPD_POS_DEPLOY_MNG_1  = "UPD_POS_DEPLOY_MNG_1"; //다운완료POS전송 플래그세팅
	public static String TB_UPD_POS_DEPLOY_MNG_2  = "UPD_POS_DEPLOY_MNG_2"; //적용완료POS전송 플래그세팅
	
	
	public static String POS_TOT_CAMPAIGN_ZIPNM     = "POS_CAMPAIGN_TOTALIMG.ZIP";
	
	
	public static final String hexArray = "0123456789ABCDEF";
	
	public static byte[] intToBytes(int value) {
		return new byte[] {
				(byte)(value >>> 8),
				(byte)value};
	}

	public static String bytesToHex(byte[] bytes) {
		if( bytes == null ) {
			return null;
		}
		final StringBuilder hex = new StringBuilder(2 * bytes.length);
		for(final byte b : bytes) {
			hex.append(hexArray.charAt((b & 0xF0) >> 4))
				.append(hexArray.charAt((b & 0x0F)));
		}
		
		return hex.toString();
	}
	
	/***
	 * getDatas
	 * Parse rcvData as msgFormName type and return(rcvData를 msgFormName의 타입으로 파싱한뒤 리턴한다).
	 * @param rcvData
	 * @param msgFormName In case of CM_HEADER, return 42Byte(CM_HEADER인경우 42Byte 리턴) 
	 * @return Receive Message(Receive 메세지) 
	 * @throws Exception
	 */
	public static  HashMap getData(String rcvData, String msgFormName) throws Exception{
		String telegram=rcvData;
		
		// If msgFormName is a header, take the designated header length 42Byte only(msgFormName이 헤더 인경우에는 지정헤더길이 42byte값만 취한다). 
		if (msgFormName.equals(CM_HEADER)){
			telegram = rcvData.substring(0,CM_LENS);
		} /*else if (msgFormName.equals(TR_HEADER)){
			telegram = rcvData.substring(CM_LENS,CM_LENS+TR_LENS);
		}*/ else {
			telegram = toData(rcvData);
		}

		//HashMap hm = (HashMap)TelegramUtil.bind(telegram, msgFormName);
		//String comCd = (String)hm.get("COM_CD");
		//hm.put("COM_CD", comCd.trim());
		return (HashMap)TelegramUtil.bind(telegram, msgFormName);		
		
	
		//return (HashMap)bind(telegram, msgFormName);
	}
	public static Map bind(String telegram, String messageFormName)
	    throws Exception
	  {
	    
		Map map = new HashMap();
		
		int nlens[]= {6,2,4,4,10,8,2,5,8,6,1,3};  
		 
		String strHeaders[] = {
				"MSG_LEN",  	
				"MSG_TYPE",
				"CMP_CD",
				"SALES_ORG_CD",
				"STOR_CD",
				"SALE_DT",
				"POS_NO",
				"TRADE_NO",
				"SYS_YMD",
				"SYS_HMS",
				"ENCRYT_MODE",
				"ERR_CD" 
			};	 
		int pre =0; 
		int next =0;
		for(int i =0; i < nlens.length; i++){
			pre = (i !=0 ? nlens[i-1] : 0);
			next = pre + nlens[i];
			map.put(strHeaders[i], telegram.substring(pre,next));
		}
		return map;
		
	  }
		  
	
	
	/***
	 * toData : Data part message(데이타부 메세지) 
	 * @param msg
	 * @return : Data Part (Message value excluding front header 42 bytes out of received data)(데이타부(수신받은 데이타중 앞부분헤더 42바이트를 제외한 메세지값))
	 */
	private static String toData(String msg){
		return msg.substring(COMMBiz.CM_LENS, msg.length());
	}
	
	/***
	 * getCommMsgType 
	 * If MSG_TYPE is not matched with the parameter type, return FALSE(이 파라미터 type과 일지하는 지 확인하여 일치하지 않으면 FALSE리턴)  
	 * @param hm : MSG_TYPE Data(MSG_TYPE데이타) 
	 * @param type
	 * @return TRUE:Matched(일치), False:Not Matched(불일치) 
	 */
	public static boolean getCommMsgType(HashMap hm, int type) {	
		int ret = toInteger((String)hm.get("MSG_TYPE"), 99);	
		
		if (ret != 99) {
			if (type == ret) return true;			
		}
				
		return false;
	}
	
	/***
	 * getCommTranYMD ---> SALE_DT 로 변경
	 * Return TRAN_YMD value(TRAN_YMD값을 리턴) 
	 * @param hm
	 * @return TRANYMD
	 */
	public static String getCommTranYMD(HashMap hm) {		
		return (String)hm.get("SALE_DT");	
	}
	
	/***
	 * getTranType
	 * @param hm
	 * @return TRAN_TYPE
	 */
	public static int getTranType(HashMap hm) {
		return toInteger((String)hm.get("TRADE_DIV"), ERR);// tran_type ===> TRADE_DIV
	}

	/***
	 * toInteger
	 * @param value
	 * @param errRet If not number, return value(숫자가 아닐경우 return value)
	 * @return
	 */
	public static int toInteger(String value, int errRet){
		int ret=0;
		
		try {			
			ret = Integer.parseInt(value);
		} catch (NumberFormatException e ){
			ret = errRet;
		}
		
		return ret;		
	}

	/***
	 * isNumber
	 * @param data
	 * @return
	 */
	public static boolean isNumber(String data){
		Pattern p = Pattern.compile("[0-9.-+]"); 
		Matcher m = p.matcher(data); 
		boolean b = m.matches();
		
		return b;
	}
	
	/***
	 * Parse getParseData rcvBuf as long as nMens length(getParseData rcvBuf를 nLens길이만큼 Parse)
	 * @param nlens
	 * @param strHeaders
	 * @param rcvBuf
	 * @return
	 */
	public static HashMap getParseData(int nlens[], String strHeaders[], String rcvBuf) {		
		int bInx=0;
		int eInx=0;	
		HashMap hm = new HashMap();
		
		eInx = nlens[0];
		for(int i=0; i<nlens.length; i++ ){
			
			hm.put(strHeaders[i].toString(), rcvBuf.substring(bInx, eInx));	
		logger.info( strHeaders[i].toString() + "==>(" + bInx +","+ eInx + ")" + rcvBuf.substring(bInx, eInx));	
			if (i<nlens.length-1){
				bInx = eInx;
				eInx = eInx+nlens[i+1];
			}
		}
		return hm;
	}	
	
	
	/***
	 * Parse getParseDataMultibyte rcvBuf as long as nMens length(getParseDataMultibyte rcvBuf를 멀티바이트 감안해 nLens길이만큼 Parse)
	 * @param nlens
	 * @param strHeaders
	 * @param rcvBuf
	 * @return
	 */
	public static HashMap getParseDataMultibyte(int nlens[], String strHeaders[], String rcvBuf) {		
		int bInx=0;
		int eInx=0;	
		HashMap hm = new HashMap();
		
		eInx = nlens[0];
		for(int i=0; i<nlens.length; i++ ){
			
			hm.put(strHeaders[i].toString(), new String(rcvBuf.getBytes(), bInx, eInx - bInx));	
			logger.info( strHeaders[i].toString() + "==>(" + bInx +","+ eInx + ")" + new String(rcvBuf.getBytes(), bInx, eInx - bInx));	
			if (i<nlens.length-1){
				bInx = eInx;
				eInx = eInx+nlens[i+1];
			}
		}
		return hm;
	}
	
	/***
	 * Parse getParseDataMultibyte rcvBuf as long as nMens length(getParseDataMultibyte rcvBuf를 멀티바이트 감안해 nLens길이만큼 Parse)
	 * @param nlens
	 * @param strHeaders
	 * @param rcvBuf
	 * @return
	 * @throws Exception
	 */
	public static String getConvertUTF16LE2UTF8(String strOrg) throws Exception {		
		byte[] byteOrg = strOrg.getBytes();
		InputStream is = new ByteArrayInputStream( byteOrg );
	    InputStreamReader isr = new InputStreamReader( is, Charset.forName("UTF-16LE") );
	    BufferedReader br = new BufferedReader( isr );
	    String strConv = br.readLine();

	    return strConv;
	}
	
	/***
	 * Parse getParseDataMultibyte rcvBuf as long as nMens length(getParseDataMultibyte rcvBuf를 멀티바이트 감안해 nLens길이만큼 Parse)
	 * @param nlens
	 * @param strHeaders
	 * @param rcvBuf
	 * @return
	 */
	public static HashMap getParseDataMultibyte2(int nlens[], String strHeaders[], String rcvBuf) {		
		int bInx=0;
		int eInx=0;	
		HashMap hm = new HashMap();
		
		eInx = nlens[0];
		for(int i=0; i<nlens.length; i++ ){
			
			hm.put(strHeaders[i].toString(), subStringMultibyte(rcvBuf, bInx, eInx, '+'));	
			//hm.put(strHeaders[i].toString(), rcvBuf.substring(bInx, eInx));	
		logger.info( strHeaders[i].toString() + "==>" + subStringMultibyte(rcvBuf, bInx, eInx, '+'));	
			if (i<nlens.length-1){
				bInx = eInx;
				eInx = eInx+nlens[i+1];
			}
		}
		return hm;
	}	
	
	
	/***
	 * Parse subStringMultibyte rcvBuf as long as nMens length(subStringMultibyte 멀티바이트를 감안해 시작위치, 끝위치 길이만큼 Parse)
	 * @param str
	 * @param bInx
	 * @param eInx
	 * @param type ('+' or '-')
	 * @return
	 */
	public static String subStringMultibyte(String str, int bInx, int eInx ,char type) {
		byte[] bytes = str.getBytes();
		int len = bytes.length;
		int length = eInx - bInx;
		int counter = 0;
		// 자를 길이가 시작위치보다 작으면 뒤에 스페이스를 붙여서 리턴
//		if (length >= len) {
//			StringBuffer sb = new StringBuffer();
//			sb.append(str);
//		
//			for(int i=0;i<length-len;i++){
//				sb.append(' ');
//			}
//			return sb.toString();
//		}

		for (int i = length - 1; i >= bInx; i--) {
			if (((int)bytes[i] & 0x80) != 0)
				counter++;
		}
		String f_str = null;
		if(type == '+'){
			f_str = new String(bytes, bInx, length + (counter % 2));
		}else if(type == '-'){
			f_str = new String(bytes, bInx, length - (counter % 2));
		}else{
			f_str = new String(bytes, bInx, length - (counter % 2));
		}
	
		return f_str;
	}
	
	
	/***
	 * Making makeSendData Response Message Header Data (makeSendData 응답 전문헤더데이타 작성하기) 
	 * @param hm Message Data(전문 데이타) 
	 * @param cmLens Message Length(전문길이) 
	 * @param ret Response Value(응답값) 
	 * @return String Message Data(전문데이타)
	 * 공통 전문 헤더 변경 SPC 용  2016.05 ( 50 BYTE -->60 BYTE
	 */
	public static String makeSendData(HashMap hmCommon, int cmLens, int ret){
		StringBuffer sb = new StringBuffer();
		int nlens[]= {6,2,4,4,10,8,2,5,8,6,1,3};  
 
		String strHeaders[] = {
				"MSG_LEN",  	
				"MSG_TYPE",
				"CMP_CD",
				"SALES_ORG_CD",
				"STOR_CD",
				"SALE_DT",
				"POS_NO",
				"TRADE_NO",
				"SYS_YMD",
				"SYS_HMS",
				"ENCRYT_MODE",
				"ERR_CD" 
			};	 
		
		hmCommon.put("MSG_LEN", StringUtil.lPad(String.valueOf(cmLens),6,"0")) ;
		hmCommon.put("SYS_YMD", (new SimpleDateFormat("yyyyMMdd")).format( new Date() )) ;
		hmCommon.put("SYS_HMS", (new SimpleDateFormat("HHmmss")).format( new Date() )) ;
		hmCommon.put("ERR_CD",   StringUtil.lPad(String.valueOf(ret),3,"0")) ;	
		
		for (int i=0; i < nlens.length ; i++) {
			StringUtil.appendSpace(sb, (String)hmCommon.get(strHeaders[i].toString()), nlens[i]);   
		}

	    //sb.append("\n");
		//sb.append("\r\n");
		return sb.toString();
	}
	
	/***
	 * Making makeSendData Response Message Header Data (makeSendData 응답 전문헤더데이타 작성하기) 
	 * @param hm Message Data(전문 데이타) 
	 * @param cmLens Message Length(전문길이) 
	 * @param ret Response Value(응답값) 
	 * @return String Message Data(전문데이타)
	 */
	public static String makeTMoneySendData(HashMap hmCommon, int cmLens){
		StringBuffer sb = new StringBuffer();
		int nlens[]= {4,3,8,4,1
					 ,1,8,3};  
		
		String strHeaders[] = {
				"TLGM_LEN",
				"WORK_CD",
				"COMPANY_CD",
				"TLGM_CD",
				"DEAL_TP",
					
				"SNDRCV_FG",
				"FILE_NM",
				"RES_CD"
			};	 
		
		hmCommon.put("TLGM_LEN", StringUtil.lPad(String.valueOf(cmLens),4,"0")) ;
		
		for (int i=0; i < nlens.length ; i++) {
			StringUtil.appendSpace(sb, (String)hmCommon.get(strHeaders[i].toString()), nlens[i]);   
		}

	    //sb.append("\n");
		//sb.append("\r\n");
		return sb.toString();
	}
	
	public static String makeHanPaySendData(HashMap<String, String> hmCommon, int cmLens) {
		StringBuffer sb = new StringBuffer();
		int nlens[] = {4,3,4,4,1
				 	  ,1,3};
		
		String strHeaders[] = {
				"TLGM_LEN",
				"WORK_CD",
				"COMPANY_CD",
				"TLGM_CD",
				"DEAL_TP",
					
				"SNDRCV_FG",
				"RES_CD"
		};
		
		hmCommon.put("TLGM_LEN", StringUtil.lPad(String.valueOf(cmLens),4,"0")) ;
		
		for (int i=0; i < nlens.length ; i++) {
			StringUtil.appendSpace(sb, (String)hmCommon.get(strHeaders[i].toString()), nlens[i]);   
		}
		
		return sb.toString();
	}
	
	public static String makeRailPlusSendData(HashMap<String, String> hmCommon, int cmLens) {
		StringBuffer sb = new StringBuffer();
		int nlens[] = {4,3,4,4,1
				 	  ,1,3};
		
		String strHeaders[] = {
				"TLGM_LEN",
				"WORK_CD",
				"COMPANY_CD",
				"TLGM_CD",
				"DEAL_TP",
					
				"SNDRCV_FG",
				"RES_CD"
		};
		
		hmCommon.put("TLGM_LEN", StringUtil.lPad(String.valueOf(cmLens),4,"0")) ;
		
		for (int i=0; i < nlens.length ; i++) {
			StringUtil.appendSpace(sb, (String)hmCommon.get(strHeaders[i].toString()), nlens[i]);   
		}
		
		return sb.toString();
	}

	public static String makeCashBeeSendData(HashMap hmCommon, int cmLens){
		StringBuffer sb = new StringBuffer();
		int nlens[]= {4,3,4,4,1
					 ,1,3};  
		
		String strHeaders[] = {
				"TLGM_LEN",
				"WORK_CD",
				"COMPANY_CD",
				"TLGM_CD",
				"DEAL_TP",
					
				"SNDRCV_FG",
				"RES_CD"
			};	 
		
		hmCommon.put("TLGM_LEN", StringUtil.lPad(String.valueOf(cmLens),4,"0")) ;
		
		for (int i=0; i < nlens.length ; i++) {
			StringUtil.appendSpace(sb, (String)hmCommon.get(strHeaders[i].toString()), nlens[i]);   
		}

	    //sb.append("\n");
		//sb.append("\r\n");
		return sb.toString();
	}

	public static String makeCardApprDataSendData(String sSendData) {
		StringBuffer sb = new StringBuffer();
		StringUtil.appendSpace(sb,sSendData,0);
		return sb.toString();
	}
	/***
	 * Parse : Json 문자열을 입력 받아서 hashmap 으로 parsing
	 * @param rcvBuf
	 * @return Hashmap 
	 */
	public static HashMap  jSonParsing(String sjson) { 		
		 
			JsonObject obj =(JsonObject) new com.google.gson.JsonParser().parse(sjson);
			//new JsonParser().parse(sjson).getAsJsonObject(); //
			Iterator i = obj.entrySet().iterator();
			
			HashMap map = new HashMap();
			while (i.hasNext()) {				 			
			    Map.Entry e = (Map.Entry)i.next(); 
			    map.put((String)e.getKey(), e.getValue());
			 }
		    return map;	
	}
	/***
	 * Make String Data : hashmap 데이터를 String 으로 생성
	 * @param  Hashmap
	 * @return String 
	 */

	public static HashMap  jSonParsing2(String json) {
		 
	    JsonObject object = (JsonObject) new com.google.gson.JsonParser().parse(json);
	    
	    Set<Map.Entry<String, JsonElement>> set = object.entrySet();
	    Iterator<Map.Entry<String, JsonElement>> iterator = set.iterator();
	    HashMap<String, Object> map = new HashMap<String, Object>();
	    while (iterator.hasNext()) {
	        Map.Entry<String, JsonElement> entry = iterator.next();
	        String key = entry.getKey();
	        JsonElement value = entry.getValue();
	        if (!value.isJsonPrimitive()) {
	            //map.put(key, jSonParsing2(value.toString()));
	        }else if (value.isJsonArray() ) {
	        	//map.put(key,value.getAsJsonArray());
	        }
	        else {
	            map.put(key, value.getAsString());
	        }
	    }
	    return map;
	}
	
	
	public static String makeMapToSendData(Map hmData) {
 		Gson gson = new GsonBuilder().disableHtmlEscaping().serializeNulls().create();
		String sb = gson.toJson(hmData);
		return sb.toString();
	}

	public static String deCodeBase64 (String encoding) throws IOException {		
		String decodestr  = new String(Base64.decode(encoding));
		return decodestr;
	}
	
	public static String enCodeBase64 (  String encoding) throws IOException {		
		String encodestr  = new String(Base64.encode(encoding.getBytes()));
		return encodestr;
	}
/* 
 *  Encoding 용 테스트 함수 2016.07 추가 		 
 */
	public static String convert(String str, String encoding) throws IOException {
		
	  ByteArrayOutputStream requestOutputStream = new ByteArrayOutputStream();
	  requestOutputStream.write(str.getBytes(encoding));
	  return requestOutputStream.toString(encoding);
	 }
	 
	public static String testEncoding(String str, String encoding) throws IOException {
	  String result = convert(str, encoding);
	  System.out.println(result + "=>encoding=" + encoding + ",length=("
	    + result.getBytes(encoding).length + ")");
	  return result;
	 }
	 /*
	 public static void main(String args[]) throws Exception {
	  System.out.println("==== file.encoding==="
	    + System.getProperty("file.encoding"));
	  String aa = "한글테스트";
	  testEncoding(aa, "MS949");
	  testEncoding(aa, "UTF-8");
	  testEncoding(aa, "CP933");
	  testEncoding(aa, "EUC-KR");
	 } */
	
	
}

