package com.eactive.eai.batch.job.jobItem.billimg;

import java.util.Properties;

import com.eactive.eai.batch.job.jobConstant.TelegramKeys;
import com.eactive.eai.batch.job.jobItem.DefaultTelegram;
import com.eactive.eai.batch.job.jobItem.TelegramService;

import com.eactive.eai.batch.rule.nodeinfo.NodeInfoManager;
import com.eactive.eai.batch.rule.nodeinfo.NodeInfoVO;
import com.eactive.eai.common.exception.ExceptionUtil;

/**
 * TSEAIBR03 의 각 노드 정보에 지정되는 클래스 이다.
 * RECV 액션을 수행하는 노드에 대해, 해당 노드에서 수행할 전문수신작업의 수신길이를 결정하기 위해 사용된다.
 */
public class RECV_BILLIMG extends DefaultTelegram implements TelegramService
{
    private final int MAX_TCP_BYTES = 8232;	//업무구분코드 이후의 송신할 전문길이의 최대값은 8232 BYTES이다.
    
    private Properties telegramInfo;
    
    /**
     * 생성자 : 어음이미지 길이 결정용 텔레그램 클래스 이다.
     */
    public RECV_BILLIMG() {
    }

    public boolean doValidation()
    {
        if (!super.doValidation()) return false;
        
        try {
        	int    currFiledIndex = 0;
    		String currFieldValue = "";
    		
	        	//1. 어음이미지수신 전문의 전문필드 개수 체크
			logger.info("{} >>>>> 수신 전문의 전문필드 개수 Checking......", logHeader);
			if (al_FieldProps == null || al_Field == null || al_FieldProps.length != al_Field.size()) {
				String errMsg = "전문필드 값 Validation 체크를 위한 데이터 불량.";
				batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
				super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_FORMAT_ERROR);
				super.setConditionTxt(TelegramKeys.ERROR);
				return false;
			}
	
			//2. 어음이미지수신 전문의 전체 전문필드 타입 체크
			logger.info("{} >>>>> 수신 전문의 전체 전문필드 타입 Checking......", logHeader);
	        for(int i=1; i<al_Field.size(); i++) {		//트랜잭션 코드는 확인하지 않음..
				if ( !this.checkType(al_FieldProps[i], new String((byte[])al_Field.get(i))) ) {
					String errMsg = ExceptionUtil.getErrorCode("BECEAIMTM010", new String[] {al_FieldNames[i], (i+1)+"", new String((byte[])al_Field.get(i)), al_FieldProps[i]});
					batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);	//수신전문의 {1} 필드(Index:{2}) 값 '{3}' 이 정의된 타입 '{4}' 에 맞지 않습니다.
					super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_FORMAT_ERROR);
					super.setConditionTxt(TelegramKeys.ERROR);
					return false;
				}
	        }
	        
	        logger.info("{} >>>>> TCP/IP 전문 송신 BYTE 수 Checking......", logHeader);
	        String tcpBytes = new String ((byte[]) al_Field.get(1));
	        try{
	        	int bytes = Integer.parseInt(tcpBytes);
	        	
	        	if (bytes > MAX_TCP_BYTES){
	        		String errMsg = "TCPIP 전문 송신 BYTES는 8232 를 초과할 수 없습니다. - ["+bytes+"]";
	        		batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
	        		super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_BYTE_ERROR);
	        		super.setConditionTxt(TelegramKeys.ERROR);
	        		return false;
	        	}
	        	
	        }catch (NumberFormatException ne){
	        	logger.error( ne.getMessage(), ne);
	        	super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_BYTE_ERROR);
	        	super.setConditionTxt(TelegramKeys.ERROR);
	        	return false;
	        }
	        
	        logger.info("{} >>>>> 업무구분코드 Checking......", logHeader);
	        currFiledIndex = 2;
			currFieldValue = new String((byte[])al_Field.get(currFiledIndex));
			if (!currFieldValue.equals(telegramInfo.getProperty(TelegramKeys.BIZ_GBN))) {
				String errMsg = ExceptionUtil.getErrorCode("BECEAIFAR006", new String[] {al_FieldNames[currFiledIndex], (currFiledIndex+1)+"", currFieldValue, telegramInfo.getProperty(TelegramKeys.BIZ_GBN)});
				batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);	//수신전문의 {1} 필드(Index:{2}) 값 '{3}' 이 '{4}' 이 아닙니다.
				super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_FORMAT_ERROR);
				super.setConditionTxt(TelegramKeys.ERROR);
				return false;
			}
			
			logger.info("{} >>>>> 거래구분코드 Checking......", logHeader);
	        currFiledIndex = 4;
			currFieldValue = new String((byte[])al_Field.get(currFiledIndex));
			if (!(currFieldValue.equals(TelegramKeys.BI_TR_CLASS_RECV) 
					|| currFieldValue.equals(TelegramKeys.BI_TR_CLASS_SEND))) {
				String errMsg = ExceptionUtil.getErrorCode("BECEAIFAR007", new String[] {al_FieldNames[currFiledIndex], (currFiledIndex+1)+"", currFieldValue, 
						TelegramKeys.BI_TR_CLASS_RECV, TelegramKeys.BI_TR_CLASS_SEND});
				batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);	//수신전문의 {1} 필드(Index:{2}) 값 '{3}' 이 '{4}' 값들 중 하나이어야 합니다.
				super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_FORMAT_ERROR);
				super.setConditionTxt(TelegramKeys.ERROR);
				return false;
			}
			
			logger.info("{} >>>>> 송수신 FLAG Checking......", logHeader);
	        currFiledIndex = 5;
			currFieldValue = new String((byte[])al_Field.get(currFiledIndex));
			if (!(currFieldValue.equals(telegramInfo.getProperty(TelegramKeys.TRA_FLAG_BANK)) 
					|| currFieldValue.equals(telegramInfo.getProperty(TelegramKeys.TRA_FLAG_CENTER)))) {
				String errMsg = ExceptionUtil.getErrorCode("BECEAIFAR007", new String[] {al_FieldNames[currFiledIndex], (currFiledIndex+1)+"", currFieldValue, 
						telegramInfo.getProperty(TelegramKeys.TRA_FLAG_BANK), telegramInfo.getProperty(TelegramKeys.TRA_FLAG_CENTER)});
				batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);	//수신전문의 {1} 필드(Index:{2}) 값 '{3}' 이 '{4}' 값들 중 하나이어야 합니다.
				super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_FORMAT_ERROR);
				super.setConditionTxt(TelegramKeys.ERROR);
				return false;
			}
			
			logger.info("{} >>>>> 응답코드  Checking......", logHeader);
	        currFiledIndex = 7;
			currFieldValue = new String((byte[])al_Field.get(currFiledIndex));
			if (!(currFieldValue.equals(TelegramKeys.BI_RES_CODE_SUCESS) || currFieldValue.equals(TelegramKeys.BI_RES_CODE_ALREADY_RECEIVED)))  {
				String errMsg = "정상거래 응답코드를 수신하지 못했습니다. 수신된 응답코드 ["+currFieldValue+"]-"+TelegramKeys.getBiImgRetDescription(currFieldValue);
				batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);	//
				super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_ETC_ERROR);
				super.setConditionTxt(TelegramKeys.ERROR);
				return false;
			}
	        
	        

        }catch (Exception e){
        	logger.error( e.getMessage(), e);
        	this.batchDoc.getBatchMsg().getBody().setErrorMsg(e.toString());
        	super.setResolveResponseCode(TelegramKeys.BI_RES_CODE_ETC_ERROR);
        	super.setConditionTxt(TelegramKeys.ERROR);
        	return false;
        }
        return true;
    }
    
    
    public boolean doExecute() {
       
        return true;
    }

    //---------------- 특정 필드값을 구하는 부분
    // 전문종별코드 필드값 리턴
    public String getTelegramType()
    {
		return super.getFieldValueString(3);
    }
    // 거래구분코드 필드값 리턴
    public String getTrClass()
    {
		return super.getFieldValueString(4);
    }
    //응답코드 필드값 리턴
    public String getResCode()
    {
		return super.getFieldValueString(7);
    }


    /**
     *  20060417 add by khs : 원치 않는 전문종별 도착시, 소켓에 있는 garvage 데이터를 없애기 위해 사용한다.
     *
     *  return value :      <0 계산 할 수 없거나 장애이다.
     *                      >0 해당 데이터를 소켓에서 더 읽어들인다.
     */
    public int getRemainDataLength()
    {
        try {
            int     idx;
            String  strLength;
    
            String  strRuleCode   = batchDoc.getBatchMsg().getHeader().getRuleCode();
            String  strPhaseCode  = batchDoc.getBatchMsg().getBody().getFlowPhaseCode();
            NodeInfoVO  vo = NodeInfoManager.getInstance().getNodeInfo(strRuleCode, strPhaseCode);
    
            idx = vo.getLengthField();
            if (idx == 0) return -1;
    
            strLength = new String((byte[])this.al_Field.get(idx-1));
            int     nDocLen = Integer.parseInt(strLength);
            int     nReceivedLen = 0;
            for (int i=2; i<this.al_FieldLength.length ; i++) {
                nReceivedLen = nReceivedLen + Integer.parseInt(this.al_FieldLength[i]);
            }
    
            return (nDocLen-nReceivedLen);
            
        } catch (Exception ex) {
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(ex.toString());
            return -1;
        }
    }
    
    public boolean doPreExecute() {
        try {
            if (!super.doPreExecute()) return false;
            telegramInfo = getTelegramInfo();
            return true;
        } catch (Exception ex) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI003";
            String errMsg = ExceptionUtil.getErrorCode (ex, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( ex.getMessage(), ex);
            return false;
        }
    }
    
    /**
     * 비정형 필드에 대한 송신 길이를 계산해서 리턴해준다.
     *
     * 필드(idx)가 비정형 필드(XX)인지 점검하고 , 해당 필드에 대한 예상 길이를 계산하여 리턴하도록 한다
     *
     * 비정형 필드를 가지고 있는 개별 Telegram Class 에서 오버라이드 필요.
     */
    public int getCalculatedLength(int idx) {
        try {
            if (idx >= this.getFieldCount() ) {
                logger.debug("{} getCalculatedLength> parameter is bigger than field count", logHeader);
                String[] msgArgs = new String[2];
                msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
                msgArgs[1] = ""+idx;
                String errCode = "BECEAIFJI011";
                String errMsg = ExceptionUtil.getErrorCode (errCode, msgArgs);
                this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
                return -1;
            }
            if (this.getFieldLength(idx).equalsIgnoreCase(TelegramService.FIELD_NO_LENGTH)) {
                //여기에서 파일을 연다.
               //return REAL_BYTE;
               
               int fieldLen = -1;
               String propKey = "";
               switch (idx) {
	       		case 0:
	       			propKey = TelegramKeys.TRCD_LEN;
	       			break;
	       		default:
	                String[] msgArgs = new String[2];
	       	        msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
	       	        msgArgs[1] = ""+idx;
	       	        String errCode = "BECEAIFJI012";
	       	        String errMsg = ExceptionUtil.getErrorCode (errCode, msgArgs);
	       	        this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
	       	        return -1;
	       		}

               fieldLen = Integer.parseInt( telegramInfo.getProperty(propKey) );               
               return fieldLen;
            } else {
                String[] msgArgs = new String[2];
                msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
                msgArgs[1] = ""+idx;
                String errCode = "BECEAIFJI012";
                String errMsg = ExceptionUtil.getErrorCode (errCode, msgArgs);
                this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
                logger.debug("{} getCalculatedLength> parameter is not FIELD_NO_LENGTH", logHeader);
                this.setConditionTxt(TelegramKeys.ERROR);
                return -1;
            }
        }catch (Exception e) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI005";
            String errMsg = ExceptionUtil.getErrorCode (e, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( e.getMessage(), e);
            this.setConditionTxt(TelegramKeys.ERROR);
            return -1;
        }
    }

    
    public int getInformalFieldSendData(int idx, byte[] data) {
    	int fldLen = getCalculatedLength(idx);
    	try {
            if (idx >= this.getFieldCount() ) {
                logger.debug("{}  getInformalFieldSendData> " +idx+ " is bigger than field count", logHeader);
                String[] msgArgs = new String[2];
                msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
                msgArgs[1] = ""+idx;
                String errCode = "BECEAIFJI011";
                String errMsg = ExceptionUtil.getErrorCode (errCode, msgArgs);
                this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
                this.setConditionTxt(TelegramKeys.ERROR);
                return -1;
            }
            switch (idx) {
            case 0:
				// TR 코드
				System.arraycopy((telegramInfo.getProperty(TelegramKeys.TRANSACTION_CODE) + "         ").getBytes(), 0, data, 0, fldLen ); 				
				break;

			default:
				break;
            }
            byte[] fieldData = new byte[fldLen];
            System.arraycopy(data, 0, fieldData, 0, fldLen);
            this.al_Field.set( idx, fieldData);
            return fldLen;
        } catch (Exception ex) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI006";
            String errMsg = ExceptionUtil.getErrorCode (ex, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( ex.getMessage(), ex);
            this.setConditionTxt(TelegramKeys.ERROR);
            return -1;
        }
    }

    
    
}
