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

import java.io.File;
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;
import java.util.Properties;

import com.eactive.eai.batch.common.LogUtil;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.server.EAIServerManager;

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


public class SEND_T0600_0001 extends DefaultTelegram implements TelegramService
{
	private Properties telegramInfo;
    private String filename;
    private File f;
    private FileInputStream fin ;
    private long fileSize = 0;

    public SEND_T0600_0001() {
    }


    /**
     * 지정된 전문의 구성 필드 배열 선언, 요구송신 파일 Start DB로그
     */
    public boolean doPreExecute() {
		if (!super.doPreExecute()) return false;

		//요구송신 파일 Start DB로그
		try {
			telegramInfo = getTelegramInfo();
			LogUtil.setLogFileStart(batchDoc);
		} catch (Exception ex) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI021";
            String errMsg = ExceptionUtil.getErrorCode (ex, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
			return false;
		}
		return true;
	}

    public boolean doExecute() {
        try {
            // 전송대상파일에 대한 네이밍 룰이 있음.
            //
            String  strFileName = batchDoc.getBatchMsg().getHeader().getFileName();
            logger.info("{} [0600] telegram : filename [" + strFileName + "]", logHeader);
            //
//            String  sendInstitutionCode ; // 송신기관       4
//            String  recvInstitutionCode ; // 수신기관       4
            String  tranClassification  ; // 거래구분       7
            String  telegramSentDate ;    // 전문 전송일    8
            String  tradeInvokedDate ;    // 거래 발생일    8
            if (strFileName.length() <31) {
                logger.debug("{} 퇴직연금 : filename inproper length [" + strFileName + "]", logHeader);
                String[] msgArgs = new String[2];
                msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
                msgArgs[1] = strFileName;
                String errCode = "BECEAIFJI034";
                String errMsg = ExceptionUtil.getErrorCode (errCode, msgArgs);
                this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
                return false;
            }
//            sendInstitutionCode = strFileName.substring(0, 4);
//            recvInstitutionCode = strFileName.substring(4, 8);
            tranClassification  = strFileName.substring(8, 15);
            telegramSentDate    = strFileName.substring(15, 23);
            tradeInvokedDate    = strFileName.substring(23, 31);
            //
            compileField(0, telegramInfo.getProperty(TelegramKeys.TRANSACTION_CODE), this.al_FieldProps[0]);
            compileField(1, telegramInfo.getProperty(TelegramKeys.BIZ_GBN), this.al_FieldProps[1]);
            // 전체 전문의 길이를 여기에서...
            long lnLength = this.getSendLength();
            if (lnLength < 0) {
                return false;
            }
            compileField(2, String.valueOf(lnLength), this.al_FieldProps[2]);
            // 자료구분 (HDB_DAT_GBN), 실테스트시에는 이 부분을 real로 바꿔야 한다.
			boolean _SYSTEMPROD = EAIServerManager.getInstance().isPEAIServer();

            if(!_SYSTEMPROD)
                compileField(3, TelegramKeys.getRPS_HDB_DAT_GBN("test"), this.al_FieldProps[3]);
            else
                compileField(3, TelegramKeys.getRPS_HDB_DAT_GBN("real"), this.al_FieldProps[3]);
            // 송신기관 구분 (HDB_SND_CLS) : 1:운영, 2:기록, 3:자산, 4:상품, 5:자산운영
            compileField(4, telegramInfo.getProperty(TelegramKeys.HDB_SND_CLS), this.al_FieldProps[4]);
            // 송신기관 코드 (HDB_SND_ID)
            compileField(5, telegramInfo.getProperty(TelegramKeys.HDB_SND_ID), this.al_FieldProps[5]);
            // 수신기관 구분 (HDB_RCV_CLS)
            compileField(6, telegramInfo.getProperty(TelegramKeys.HDB_RCV_CLS), this.al_FieldProps[6]);
            // 수신기관 코드 (HDB_RSV_ID) <-- 파일명에서 5~8번째 바이트를 취함
            compileField(7, batchDoc.getBatchMsg().getHeader().getFileName().substring(4, 8), this.al_FieldProps[7]);
            // 전문종별코드
            compileField(8, this.getFldTelegramType(), this.al_FieldProps[8]);
            // 거래구분코드
            compileField(9, tranClassification, this.al_FieldProps[9]);
            // 송수신 Flag
            compileField(10,TelegramKeys.RPS_HDB_TRA_FLAG_CLIENT, this.al_FieldProps[10]);
            // STATUS : 사용안함
            compileField(11, "000", this.al_FieldProps[11]);
            // 응답코드
            compileField(12, TelegramKeys.RPS_HDB_RET_CODE_SUCCESS, this.al_FieldProps[12]);
            // 전문전송일
            compileField(13, telegramSentDate, this.al_FieldProps[13]);
            // 전문전송시간
            compileField(14, TelegramKeys.getHHMMSS(), this.al_FieldProps[14]);
            // 송신기관전문번호, 8자리 : Random 번호를 만들것인가? 일련번호를 만들것인가?
            // AS-IS 현행과 일단 동일하게...
            // compileField(15, TelegramKeys.getSendSequence(this.getFldTelegramType()), this.al_FieldProps[15]);
            compileField(15, "00000002", this.al_FieldProps[15]);
            // 수신기관전문번호
            compileField(16, TelegramKeys.RPS_HDB_RSV_DOCSEQ, this.al_FieldProps[16]);
            // 거래발생일, 실 자료의 거래 발생일, 실 파일의 19번째부터 8자리를 읽어야 한다.
            compileField(17, tradeInvokedDate, this.al_FieldProps[17]);
            // 전체파일수 : 사용안함
            compileField(18, TelegramKeys.RPS_HDB_TOT_FILE, this.al_FieldProps[18]);
            // 현재파일순번 : 사용안함
            compileField(19, TelegramKeys.RPS_HDB_CUR_FILE, this.al_FieldProps[19]);
            // 현재 파일명
            compileField(20, batchDoc.getBatchMsg().getHeader().getFileName(), this.al_FieldProps[20]);
            // 현재 파일 전체 전문 수 : 사용안함
            compileField(21, TelegramKeys.RPS_HDB_CUR_TOT, this.al_FieldProps[21]);
            // 현재 파일 현재 순번
            compileField(22, TelegramKeys.RPS_HDB_CUR_NOW, this.al_FieldProps[22]);
            // 전문 CASE 명
            compileField(23, TelegramKeys.RPS_HDB_DOC_CASE, this.al_FieldProps[23]);
            // 송신추가정의
            compileField(24, TelegramKeys.RPS_HDB_SND_EXT, this.al_FieldProps[24]);
            // 송신추가정의
            compileField(25, TelegramKeys.RPS_HDB_RSV_EXT, this.al_FieldProps[25]);
            //<< 공통헤더 전문 완성
            //>> 파일헤더 및 내용, 트레일러 만들기
            //<< 최종 길이 셋팅
            return true;
        } catch (Exception e) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIJI001";
            String errMsg = ExceptionUtil.getErrorCode (e, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( e.getMessage(), e);
        }
        return false;
    }

    /**
     * 실제 송신할 전문의 총길이를 리턴해준다.
     */
    public int getSendLength()
    {
        try {
            int nSumFormalField = 0;
            for (int i=0; i<this.al_FieldLength.length ; i++) {
                String strFieldLength = this.al_FieldLength[i];
                if (!strFieldLength.equalsIgnoreCase(FIELD_NO_LENGTH)) {
                    try {
                        int nFldCnt = Integer.parseInt(strFieldLength);
                        nSumFormalField = nSumFormalField + nFldCnt;
                    } catch(Exception ex) {
                        logger.error( ex.getMessage(), ex);
                        byte[] aField = (byte[])this.al_Field.get(i);
                        nSumFormalField = nSumFormalField + aField.length;
                    }
                }
            }

            // 전체 전문의 길이를 여기에서...
            String fileDir = batchDoc.getBatchMsg().getHeader().getFilePath();
            String fileNm  = batchDoc.getBatchMsg().getHeader().getRenamedFileName();

            this.filename = fileDir+ File.separator + fileNm;
            this.f = new File(this.filename);
            if (!f.exists()) // 파일이 없으면 리턴 False
            {
                logger.debug("{}  the File does not exist!!! ["+this.filename+"]", logHeader);
                String[] msgArgs = new String[1];
                msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
                String errCode = "BECEAIJI022";
                String errMsg = ExceptionUtil.getErrorCode (errCode, msgArgs);
                this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
                return -1;
            }
            this.fileSize = f.length();
            int nLength = (int)f.length() + nSumFormalField;
            fin = new FileInputStream(f);

            return nLength;
        } 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;
        }
    }

    /**
     * 비정형 필드에 대한 송수신 길이를 계산해서 리턴해준다.
     * 필드(idx)가 비정형 필드(XX)인지 점검하고 , 해당 필드에 대한 예상 길이를 계산하여 리턴하도록 한다
     * 비정형 필드를 가지고 있는 개별 Telegram Class 에서 오버라이드 필요.
     */
    public int getCalculatedLength(int idx)
    {
         try {
            //  여기서는 전송대상인 파일의 크기를 리턴해준다.
            logger.info("{} batch transefet job : Target file size = ["+this.fileSize+"]", logHeader);

            batchDoc.getBatchMsg().getHeader().setFileSize(this.fileSize);


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

    /**
     * 여기서는 파일을 닫는다.
     */
    public boolean doPostExecute() {
        try {
            if (!super.doPostExecute()) return false;

			//DB로그에 남길 파일 헤더,트레일러 내용 설정
			super.setFileHeaderAndTrailer(f);

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

            fin.close();
            logger.info("{}  doPostExecute called : file close", logHeader);
            return true;

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

    /**
     * OffSet은 FileInputStream 에 의해 자동관리 된다.
     */
    public int getInformalFieldSendData(int idx, byte[] data) {
        try {
            int rc = fin.read(data, 0, data.length);
            
            long lnCurSize = batchDoc.getBatchMsg().getBody().getCurFileSize() + rc;
            batchDoc.getBatchMsg().getBody().setCurFileSize(lnCurSize);  //파일사이즈 설정 (전송 진행상태 확인용)
            return rc;
            
        } catch (Exception ex) {
            logger.error("{} ★★★★★ 송신 파일 데이터 READ 시 오류 발생 !! ★★★★★", logHeader, ex);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(ex.toString());
            return -1;
        }
    }

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

}
