package com.eactive.eai.inbound;

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

import com.eactive.eai.batch.job.jobConstant.TelegramKeys;

import com.eactive.eai.batch.scheduler.ScheduleSendProcess;

import com.eactive.eai.batch.common.BatchDirUtil;
import com.eactive.eai.batch.common.CalendarUtil;
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.doc.BatchDoc;
import com.eactive.eai.batch.message.EAIBatchMsgManager;
import com.eactive.eai.batch.osd.OutsideManager;
import com.eactive.eai.batch.osd.OutsideVO;
//import com.eactive.eai.batch.xecure.XecureManager;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.property.PropManager;
import com.eactive.eai.common.routing.Process;
import com.eactive.eai.common.util.Logger;

public class FileEventListener extends Process{
	
    // FileLoger
    static Logger logger = Logger.getLogger(Logger.LOGGER_FILEEVENT);
	private String targetDir;
//	private String errorDir;
	private BatchDoc batchMsgDoc ;
	private String dirPath;
	private String fileName;

    public void procFileEvent(String recvdirPath, String recvfileName, String line){

    	String chkExt = BatchDirUtil.getRequestRootExt();
    	dirPath  = recvdirPath;
    	fileName = recvfileName.substring(0, recvfileName.length()-chkExt.length());
    	
    	try {
        	getFileEventInfo();
        	callFileMover();
    		closeLog();
    		
    		batchMsgDoc.getBatchMsg().getHeader().setHdrInfoName(line);
    		
    		ScheduleSendProcess process = new ScheduleSendProcess();
    		process.proc(batchMsgDoc);
		} catch (Exception e) {
			catchException(e);
		}
    }
    private void getFileEventInfo() throws Exception
    {
        // 수신한 파일 정보
        logger.info("[Send File Event] =========================================================================");
        logger.info("[Send File Event] ▶▶▶▶▶▶▶▶▶▶ Local 송신 FILE EVENT 발생 !! ◀◀◀◀◀◀◀◀◀◀");
        logger.info("[Send File Event] ※ Event 디렉토리  : [" + dirPath         +"]");
        logger.info("[Send File Event] ※ Event 파일명    : [" + fileName        +"]");
        logger.info("[Send File Event] =========================================================================");

		//업무구분코드
        String processCode     = fileName.substring(0,  5);
        String institutionCode = fileName.substring(6, 10);
        logger.info("processCode     = " + processCode);
        logger.info("institutionCode = " + institutionCode);

		//거래구분 코드 설정
		int bizCodeStartIndex  = 0;
		int bizCodeEndIndex    = 0;
		int orgIndex           = 0;
		OutsideVO organInfo    = OutsideManager.getInstance().getOutsideInfo(processCode, institutionCode);
		String institutionName = organInfo.getOsdName();
		String processName     = organInfo.getBatchName();
		bizCodeStartIndex      = organInfo.getBizCdStartIdx();
		bizCodeEndIndex        = organInfo.getBizCdEndIdx();
		orgIndex               = organInfo.getBizCdEndIdx();
        logger.info("processName     = " + processName);

        String sFileName = fileName.substring(11);
		if (bizCodeStartIndex <= 0 || bizCodeStartIndex >= sFileName.length()) bizCodeStartIndex = 0;
		if (bizCodeEndIndex   == 0 || bizCodeEndIndex   >  sFileName.length()) bizCodeEndIndex = sFileName.length();
		if (bizCodeEndIndex   < 0 &&  0  <  sFileName.length() + bizCodeEndIndex ) bizCodeEndIndex = sFileName.length() + bizCodeEndIndex;
        String bizCode = sFileName.substring(bizCodeStartIndex, bizCodeEndIndex);
        
        // 거래 구분 코드 길이가 가변인 경우( END INDEX가 0인 경우)
        if ( orgIndex == 0 ){
	        String delStr = null;
	        try {
	        	Properties orgInfo = PropManager.getInstance().getProperties(   TelegramKeys.PROP_GROUP_NAME_PREFIX
	                        + "{" + processCode + "_" + institutionCode + "}");
	            delStr = orgInfo.getProperty( "del.string" );
			} catch (Exception e) {}

	        if ( delStr != null && !delStr.trim().equals("")){
	        	int delIndex = bizCode.indexOf(delStr);
	        	if ( delIndex > -1 ) {
	        		bizCode = bizCode.substring(0, delIndex );
	        	}
	        }
        }
        
		logger.info("[Send File Event] -------------------------------------------------------------------------");
		logger.info("[Send File Event] ■ File Event 파싱 정보");
		logger.info("[Send File Event] - 수신디렉토리: [" + dirPath          +"]");
		logger.info("[Send File Event] - 수신파일명  : [" + sFileName         +"]");
		logger.info("[Send File Event] - 업무구분코드: [" + processCode      +"] (업무구분명: "+ processName     +")");
		logger.info("[Send File Event] - 대외기관코드: [" + institutionCode  +"] (대외기관명: "+ institutionName +")");
		logger.info("[Send File Event] - 거래구분코드: [" + bizCode          +"]");
		logger.info("[Send File Event] -------------------------------------------------------------------------");

        /* 저장할 디렉토리 및 파일정보
         * sourceDir : 파일을 읽어올 최상위 디렉토리
         * targetDir : 파일을 저장할 디렉토리
         *
         * 현재는 FileEvent에 의해서 옮겨지는 Arch디렉토리가 읽어 올 디렉토리가 된다. (sourceDir)
         *        Arch 디렉토리에 있는 파일을 읽어서 Arch디렉토리 밑에 업무코드명과 동일하게 디렉토리를 만들고 저장한다.
         */
        targetDir = BatchDirUtil.getRequestArchDir() +"/"+ processCode +"/"+ institutionCode ;
        //errorDir  = BatchDirUtil.getRequestErrorDir()+"/"+ processCode +"/"+ institutionCode ;

        /*
         * FileEvent가 SchedulerProcess로 전달할 기본 EAIBatchMsg를 생성한다.
         * FileEventListener가 입력가능한 값들은 EAIBatchMsg의 항목 중 다음과 같다.
         *  - UUID
         *  - Layer 구분 코드 (한시적)
         *  - ProcessCode: 수신한 서브디렉토리와 동일
         *  - FileName : 송수신 원 파일명
         *  - FilePath : 파일이 실재 존재하는 디렉토리
         *  - RenamedFileName : 저장후 이름이 변경된 파일명
         */
        // BatchMsgDoc 생성
        batchMsgDoc = EAIBatchMsgManager.createBatchMsgWithUUID(false);  //UUID 생성, false:초기화안함
		EAIBatchMsgManager.updateBatchMsgWithStageTime(batchMsgDoc, CommonKeys.LAYER_FILE_EVENT, CommonKeys.SUB_LAYER_FILE_EVENT);  // layer, flowPahse, 시작시간 설정
        batchMsgDoc.getBatchMsg().getHeader().setProcessCode(processCode);                     // 업무코드
        batchMsgDoc.getBatchMsg().getHeader().setProcessType(CommonKeys.PROCESS_REQUEST_SEND); // 업무유형 (요구송신 설정)
        batchMsgDoc.getBatchMsg().getHeader().setInstitutionCode(institutionCode);             // 대외기관코드
        batchMsgDoc.getBatchMsg().getHeader().setFileName(sFileName);                           // 원 파일명
        batchMsgDoc.getBatchMsg().getHeader().setFilePath(targetDir);                          // 파일이 실재 존재하는 디렉토리
        batchMsgDoc.getBatchMsg().getHeader().setFileErrorPath(targetDir);                      // 장애발생시 실파일이 이동할 디렉토리를 지정한다.
        batchMsgDoc.getBatchMsg().getHeader().setBizCode(bizCode);                              // 거래구분코드
    }

    private void callFileMover() throws Exception
    {
        String renamedFileName = fileName.substring(11) + "_" + CalendarUtil.getCurrentTimeNoDash();
        File realFile = new File(this.dirPath +"/"+ fileName);
        File archFile = new File(this.targetDir +"/"+ renamedFileName);

        //Root 디렉토리에서 Arch 디렉토리로 파일 이동
		logger.info("[Send File Event] -------------------------------------------------------------------------");
		logger.info("[Send File Event] ■ 요구송신 파일 이동 (송신_Real -> 송신_Arch)");
		logger.info("[Send File Event] - Real 디렉토리: ["+ this.dirPath +"/"+ fileName   +"] (exists: "+ realFile.exists() +")");
		logger.info("[Send File Event] - Arch 디렉토리: ["+ this.targetDir +"/"+ renamedFileName +"] (exists: "+ archFile.exists() +")");
        logger.info("[Send File Event] - 변경된 파일명: " + renamedFileName);
		logger.info("[Send File Event] -------------------------------------------------------------------------");

		boolean isSuccessMoveFile = FileUtil.copyTransferFile(realFile, archFile, true);
        
        if (!isSuccessMoveFile) {
			String errMsg = ExceptionUtil.getErrorCode("BECEAIIFE002", new String[] {realFile.getAbsolutePath(), archFile.getAbsolutePath()});
			throw new Exception(errMsg); //요구송신 데이터파일을 송신_Real 디렉토리({1})에서 송신_Arch 디렉토리({2})로 이동시 실패하였습니다.
        }
        batchMsgDoc.getBatchMsg().getHeader().setRenamedFileName(renamedFileName);   //변경된 파일명 설정
    }
    private void closeLog() throws Exception
    {
        // 종료시간을 추가한다.
        batchMsgDoc.getBatchMsg().getBody().setPhaseEndTime(CalendarUtil.getCurrentTimeNoDash());

        // 요구송신에 대한 최초 DB로그. StartLog 호출.
        LogUtil.setStartLog (batchMsgDoc);
        logger.info("[Send File Event] ※ Event 파일명  : [" + fileName        +"]");

    }
    
    private void catchException(Exception ex)
    {
        try {
            // 파일로그 처리
            String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIIFE001");
            logger.error(errMsg, ex);   //Local 송신 File Event Listener 에서 오류가 발생하였습니다.

            // DB로그 처리
            batchMsgDoc.getBatchMsg().getBody().setErrorMsg(errMsg);
            batchMsgDoc.getBatchMsg().getBody().setPhaseEndTime(CalendarUtil.getCurrentTimeNoDash());
            LogUtil.setErrorLog(batchMsgDoc, errMsg);

        } catch (Exception e) {
            logger.error("[Send File Event] ★★★★★ Local 송신 File Event Listner 예외 처리 중 에러 !! ★★★★★", e);
        }
    }
	@Override
	public BatchDoc clientRequestwithReturn(
			BatchDoc batchDoc) throws Exception {
		return null;
	}
	@Override
	public void clientRequest() throws Exception {
	}
}