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

import java.io.ByteArrayOutputStream;
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.encrypt.EncryptManager;
import com.eactive.eai.common.exception.ExceptionUtil;

public class SEND_BI0200 extends DefaultTelegram implements TelegramService
{

    private int SEND_LENGTH;        //TCP/IP전문 송신 BYTES수로 "업무구분코드"이후의 송신할 전문 길이
    private int REAL_SEND_LENGTH;  //실제 송신할 전문의 총길이

    private Properties telegramInfo;
    /**
     * 생성자
     */
    public SEND_BI0200() {
        //업무개시요구 및 업무개시통보
    }

    /**
     * 전문조립
     */
    public boolean doExecute() {
        try {
            boolean result = calculateSendLength();
            if (!result) return false;

            // TRANSACTION CODE로 은행에서 필요할 경우 센터에서 SET
            //compileField(0, telegramInfo.getProperty(TelegramKeys.TRANSACTION_CODE), this.al_FieldProps[0]);
            //TCP/IP전문 송신 BYTES수로 "업무구분코드"이후의 송신할 전문 길이
            compileField(1, ""+SEND_LENGTH, this.al_FieldProps[1]);
            //업무구분코드 - 센터 및 은행에서 업무구분을 위하여 SET
            compileField(2, telegramInfo.getProperty(TelegramKeys.BIZ_GBN), this.al_FieldProps[2]);
            //전문종별코드. 전문의 기능을 나타냄.
            compileField(3, this.getFldTelegramType(), this.al_FieldProps[3]);
            //거래구분코드 "R"-센터 수신 업무, "S"-센터 송신업무
            compileField(4, this.getFldTrClass(), this.al_FieldProps[4]);
            //송수신 FLAG "C"-센터에서 전문을 발생할 시, "B"-은행에서 전문을 발생할 시
            compileField(5, telegramInfo.getProperty(TelegramKeys.TRA_FLAG_BANK), this.al_FieldProps[5]);
            //화일명
            compileField(6, " ", this.al_FieldProps[6]);
            //응답코드
            compileField(7, TelegramKeys.RPS_HDB_RET_CODE_SUCCESS, this.al_FieldProps[7]);
            //전문 전송 일시 (MMddhhmmss)
            compileField(8, TelegramKeys.getMMddHHmmss(), this.al_FieldProps[8]);
            //송신자명 (어음이미지시스템의 책임자 ID)
            compileField(9, batchDoc.getBatchMsg().getHeader().getUserID(), this.al_FieldProps[9]);
            //송신자 암호 (정당한 송신자 확인을 위한 쌍방간 합의된 암호
            //compileField(10, batchDoc.getEAIBatchMessage().getHeader().getUserPassword(), this.al_FieldProps[10]);
            String cypherYn = telegramInfo.getProperty(TelegramKeys.CMS_CIPHER_USE);
            if (( cypherYn != null) &&cypherYn.equalsIgnoreCase("Y") ) {
            	//전송자명은 앞에서 8자리이며 8자리 미만은 Z로 채움..
            	String passwd = EncryptManager.getInstance().getEncryptPwd((batchDoc.getBatchMsg().getHeader().getUserID()+"ZZZZZZZ").substring(0,8),
            			                                                (batchDoc.getBatchMsg().getHeader().getUserPassword() + "ZZZZZZ").substring(0,6),
            			                                                telegramInfo.getProperty(TelegramKeys.BANK_CODE).substring(1,3),
            			                                                TelegramKeys.getYYYYMMddHHmmss().substring(2,8));
                compileField(10, passwd, this.al_FieldProps[10]);
                logger.debug("{} SEND_BI0200 ] PASSWD : "+passwd, logHeader);                
            }else{
                compileField(10, batchDoc.getBatchMsg().getHeader().getUserPassword(), this.al_FieldProps[10]);
            }
            //<< 전문 완성
            return true;
        } catch (Exception e) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI001";
            String errMsg = ExceptionUtil.getErrorCode (e, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( e.getMessage(), e);
            return false;
        }

    }

    /**
     * 실제 송신할 전문의 총길이를 리턴해준다.
     */
    public int getSendLength()
    {
        try {
            return REAL_SEND_LENGTH;  //실 DATA BYTE수
        } catch (Exception e) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI013";
            String errMsg = ExceptionUtil.getErrorCode (e, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( e.getMessage(), e);
            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;
        }
    }

    public boolean doPostExecute() {
        if (!super.doPostExecute()) return false;
        try {
			//DB로그에 남길 전문 헤더 설정
            ByteArrayOutputStream baout = new ByteArrayOutputStream();
            for (int i=0; i<8; i++) { //어음이미지 전문의 헤더는 응답코드까지 임.
                byte[] barr = (byte[])this.al_Field.get(i);
                if ( barr[0] != '\0') {
                    baout.write((byte[])this.al_Field.get(i));
                }
            }
            batchDoc.getBatchMsg().setTelegramHeader(new String(baout.toByteArray()));

            //DB로그에 남길 전문 바디 설정
            baout = new ByteArrayOutputStream();
            for (int i=8; i< al_Field.size(); i++) {
                baout.write((byte[])this.al_Field.get(i));
            }
            batchDoc.getBatchMsg().setTelegramBody(new String(baout.toByteArray()));

            return true;

        } catch(Exception ex) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI002";
            String errMsg = ExceptionUtil.getErrorCode (ex, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( ex.getMessage(), ex);
            return false;
        }
    }


    private boolean calculateSendLength () {
        try {
        	for (int i=2; i< this.al_Field.size(); i++) {
                byte[] aField = (byte[]) this.al_Field.get(i);
                SEND_LENGTH += aField.length;
            }
            REAL_SEND_LENGTH = SEND_LENGTH;
            for (int i=1; i < 2 ; i++) {
                byte[] aField = (byte[]) this.al_Field.get(i);
                REAL_SEND_LENGTH += aField.length;
            }
            REAL_SEND_LENGTH +=getCalculatedLength(0);
        } catch (Exception e) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI025";
            String errMsg = ExceptionUtil.getErrorCode (e, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( e.getMessage(), e);
            return false;
        }
        return true;
    }
    
    /**
     * 비정형 필드에 대한 송신 길이를 계산해서 리턴해준다.
     *
     * 필드(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);
                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);
            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);
                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);
            return -1;
        }
    }

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

