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

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.Socket;
import java.util.ArrayList;

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.common.CommonKeys;
import com.eactive.eai.batch.common.FileUtil;
import com.eactive.eai.batch.common.LogUtil;
import com.eactive.eai.batch.osd.OutsideManager;
import com.eactive.eai.batch.osd.OutsideVO;
import com.eactive.eai.batch.rule.dirInfo.BatchJobInfoVO;
import com.eactive.eai.batch.rule.dirInfo.DirInfoManager;
import com.eactive.eai.batch.rule.kikwanInfo.KikwanInfoManager;
import com.eactive.eai.batch.rule.kikwanInfo.KikwanInfoVO;
import com.eactive.eai.batch.running.BatchRunningJobManager;
import com.eactive.eai.batch.scheduler.SchedulerMessageManager;
import com.eactive.eai.batch.scheduler.SchedulerMessageVO;
import com.eactive.eai.common.exception.ExceptionUtil;

public class RECV_FTBAT_0200 extends DefaultTelegram implements TelegramService
{
    /**
     * 생성자
     */
	private ByteArrayOutputStream bout;
	
	public RECV_FTBAT_0200() {
        //업무개시요구 및 업무개시통보
		bout = new ByteArrayOutputStream();
	}

    /**
     * 전문 해체하기
     */
    public boolean doExecute() {
        if (!super.doExecute()) return false;
        int fileNameLen = bout.toByteArray().length - 1;
        byte[] filename = new byte[fileNameLen];
        System.arraycopy(bout.toByteArray(), 0, filename, 0, fileNameLen);
        setFieldDataByIndex(4,filename);
        return true;
    }

    /**
     * 전문 Validation
     */
    public boolean doValidation()
    {
        if (!super.doValidation()) return false;

    	setResolveResponseCode("0000");
        logger.info("{} BATCH JOB : start request received", logHeader);
        // 거래구분코드(송수신 구분 코드) 체크
        String recvTrGbCd = getFieldValueString(2);
        String recvKikwanCode = getFieldValueString(3).trim();
        
        String recvFileName = getFieldValueString(4).trim();
        if ( "100010".equals(recvTrGbCd)){
            logger.info("{} BATCH JOB : send request received", logHeader);
            batchDoc.getBatchMsg().getHeader().setProcessType(CommonKeys.PROCESS_RESPONSE_SEND);
            checkMoreFileinDB(recvFileName);
        }else if ( "100020".equals(recvTrGbCd)){
            logger.info("{} BATCH JOB : recv request received", logHeader);
            setConditionTxt(TelegramKeys.RECV);
            batchDoc.getBatchMsg().getHeader().setProcessType(CommonKeys.PROCESS_RESPONSE_RECEIVE);
            if ( !procRecv(recvFileName) )
            	return true;
        }else{
            logger.info("{} BATCH JOB : send/recv request error", logHeader);
            this.setResolveResponseCode(TelegramKeys.RES_CODE_FORMAT_ERROR);
            setConditionTxt(TelegramKeys.ERROR);
        }
        KikwanInfoVO vo = KikwanInfoManager.getInstance().getKikwanInfo(recvKikwanCode);
        batchDoc.getBatchMsg().getHeader().setTRXID(recvKikwanCode);
        
        String strUUID = batchDoc.getBatchMsg().getHeader().getUUID();
        Socket socket =  BatchRunningJobManager.getInstance().getRunningSocket(strUUID);
        batchDoc.getBatchMsg().getHeader().setRemoteIP(socket.getRemoteSocketAddress().toString().substring(1,socket.getRemoteSocketAddress().toString().indexOf(":") ));
        
        if ( vo == null || !vo.getSysIp().equals(batchDoc.getBatchMsg().getHeader().getRemoteIP()) ){
        	setConditionTxt(TelegramKeys.NOFILE);
        	setResolveResponseCode("B001");
        	batchDoc.getBatchMsg().getBody().setErrorMsg("Your IP is not authorized[" + batchDoc.getBatchMsg().getHeader().getRemoteIP()+ "]");
        }else{
        }

        return true;
    }

    public boolean doPreExecute() {
        try {
            if (!super.doPreExecute()) return false;
            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=1; i<2; i++) {
                baout.write((byte[])this.al_Field.get(i));
            }
            batchDoc.getBatchMsg().setTelegramHeader(new String(baout.toByteArray()));

            //DB로그에 남길 전문 바디 설정
            baout = new ByteArrayOutputStream();
            for (int i=2; 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;
        }
    }

    /**
     * int getCalculatedLength(int idx)
     * --------------------------------------------------------------------------------------
     * 전달된 인덱스 idx는 비정형 필드여야 한다. 즉 필드의 길이값이 FILE_NO_LENGTH("XX") 이어야 한다.
     * 해당 비정형 필드에 대해 실질적인 전문길이를 동적으로 계산해 낸다.
     * SEND : 송신 길이 계산
     * RECV : 수신 길이 계산
     */
    public int getCalculatedLength(int idx) {
        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 51;
        } 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);
            return -1;
        }
    }

    public boolean doInformalField(int idx, byte[] data, int length)
    {
        try {
        	bout.write(data, 0, length);
        } catch (Exception ex) {
            String[] msgArgs = new String[1];
            msgArgs[0] = this.batchDoc.getBatchMsg().getHeader().getProcessCode();
            String errCode = "BECEAIFJI004";
            String errMsg = ExceptionUtil.getErrorCode (ex, errCode, msgArgs);
            this.batchDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            logger.error( ex.getMessage(), ex);
            return false;
        }
        return true;
    }
    
    private void checkMoreFileinDB(String fileName){
        String processCode = batchDoc.getBatchMsg().getHeader().getProcessCode();
        String institutionCode = batchDoc.getBatchMsg().getHeader().getInstitutionCode();
        SchedulerMessageVO info;
        try{
            info = SchedulerMessageManager.getInstance().getSendJobFromQueue(processCode, institutionCode, fileName );
            if ( info == null ) {
                this.setConditionTxt(TelegramKeys.NOFILE);
            	setResolveResponseCode("F001");
            	batchDoc.getBatchMsg().getBody().setErrorMsg("File not found [" + fileName + "]");
                return;
            }
            String strUUID = batchDoc.getBatchMsg().getHeader().getUUID();
            String strSubUUID = batchDoc.getBatchMsg().getBody().getSubUUID();

            //해당 작업을 Job_Queue 테이블에서 Job_Processing 테이블로 이동
            SchedulerMessageManager.getInstance().moveJobQueueToHandleWithNewID(info, strUUID, strSubUUID);

            //BatchMsgDoc 값 설정
            batchDoc.getBatchMsg().getHeader().setScheduleCode(info.getScheduleCode());
            batchDoc.getBatchMsg().getHeader().setScheduleSTime(info.getStartTime());
            batchDoc.getBatchMsg().getHeader().setScheduleETime(info.getEndTime());
            batchDoc.getBatchMsg().getHeader().setFilePath(info.getFilePath());
            batchDoc.getBatchMsg().getHeader().setFileName(info.getFileName());
            batchDoc.getBatchMsg().getHeader().setRenamedFileName(info.getRenamedFileName());
            batchDoc.getBatchMsg().getHeader().setJobCode(info.getJobCode());
            batchDoc.getBatchMsg().getHeader().setBizCode(info.getBizCode());
            batchDoc.getBatchMsg().getHeader().setFlowCode(info.getFlowRuleCode());
            batchDoc.getBatchMsg().getHeader().setRuleCode(info.getFlowRuleCode());
            batchDoc.getBatchMsg().getHeader().setBlockSize(info.getBlockSize());
            batchDoc.getBatchMsg().getHeader().setSequenceSize(info.getSequenceSize());
            batchDoc.getBatchMsg().getHeader().setPacketSize(info.getPacketSize());
            batchDoc.getBatchMsg().getHeader().setHdrInfoName(info.getHdrInfoName());
            batchDoc.getBatchMsg().getHeader().setTotRecCnt(0);
            this.setConditionTxt(TelegramKeys.SEND);
            LogUtil.updateLogMaster(batchDoc);
            LogUtil.setLogFileStart(batchDoc);
        } catch ( Exception e){}
    }

    
    private boolean procRecv(String fileName){
        //파일명으로 부터 거래 구분 코드 추출
        int bizCodeStartIndex = 0;
        int bizCodeEndIndex   = 0;
        String processCode = batchDoc.getBatchMsg().getHeader().getProcessCode();
        String institutionCode = batchDoc.getBatchMsg().getHeader().getInstitutionCode();
        ArrayList<OutsideVO> organList = OutsideManager.getInstance().getOutsideInfo(processCode);
        for (int i=0; organList!=null && i<organList.size(); i++) {
            OutsideVO organInfo = organList.get(i);
            if ( institutionCode.equals(organInfo.getOsdCode()) ) {
                bizCodeStartIndex = organInfo.getBizCdStartIdx();
                bizCodeEndIndex   = organInfo.getBizCdEndIdx();
                break;
            }
        }
        if (bizCodeStartIndex <= 0 || bizCodeStartIndex >= fileName.length()) bizCodeStartIndex = 0;
        if (bizCodeEndIndex   <= 0 || bizCodeEndIndex   >  fileName.length()) bizCodeEndIndex = fileName.length();
        String bizCode = fileName.substring(bizCodeStartIndex, bizCodeEndIndex);
        batchDoc.getBatchMsg().getHeader().setBizCode(bizCode);

        BatchJobInfoVO bJobInfo = DirInfoManager.getInstance().getFileInfoByDstcd(processCode, bizCode);
        if ( bJobInfo == null || !bJobInfo.getRecvUseYN().equals("1") ){
        	setResolveResponseCode("F003");
        	batchDoc.getBatchMsg().getBody().setErrorMsg("This is not a REGISTERED FILE[" + fileName+ "]");
        	return false;
        }

        String pattern = null;
        if ( bJobInfo!= null ){
            pattern = bJobInfo.getSndrcvFileName();
        }

        String recvFileName = FileUtil.getRecvFileName(fileName, pattern, batchDoc, false);
        batchDoc.getBatchMsg().getHeader().setFileName(fileName);
        batchDoc.getBatchMsg().getHeader().setRenamedFileName(recvFileName);
        batchDoc.getBatchMsg().getHeader().setTotRecCnt(0);
        
        String fileDir = batchDoc.getBatchMsg().getHeader().getFilePath();
        logger.debug("{}  DIR = <<"+fileDir+">> FILE >> Tele FName <<"+recvFileName+">>", logHeader);
        if (fileDir.charAt(fileDir.length()-1) != File.separatorChar) {
            fileDir = fileDir + File.separator;
        }
        String fileFullName = fileDir + recvFileName;

        File file = new File(fileFullName);
        if (file.exists() && file.length() > 0) {
            //파일 수신시에 미완료된 파일은 처음부터 받는다.  따라서 기존 파일 삭제
            file.delete();
        }
        //수신 파일 End DB로그
        try {
			LogUtil.setLogFileStart(batchDoc);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}
        return true;

    }

    //---------------- 특정 필드값을 구하는 부분
    // 전문종별코드 필드값 리턴
    public String getTelegramType(){
        return super.getFieldValueString(1);
    }
}