package com.eactive.eai.inbound;

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.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.scheduler.SchedulerMessageManager;
import com.eactive.eai.batch.scheduler.SchedulerMessageVO;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.routing.Process;
import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.common.util.Logger;

public class ReqRecvEventListener extends Process{
	
    // FileLoger
    static Logger logger = Logger.getLogger(Logger.LOGGER_FILEEVENT);
	private BatchDoc batchMsgDoc ;
	private String dirPath;
	private String fileName;
	private SchedulerMessageVO info;
    private String processCode;
    private String institutionCode;


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

    	dirPath  = recvdirPath;
    	fileName = recvfileName;
    	
    	try {
        	getFileEventInfo();
        	callFileMover();
    		closeLog();
			
		} catch (Exception e) {
			catchException(e);
		}
    }
    private void getFileEventInfo() throws Exception
    {
        // 수신한 파일 정보
        logger.info("[Req Recv File Event] =========================================================================");
        logger.info("[Req Recv File Event] ▶▶▶▶▶▶▶▶▶▶ Local 송신 FILE EVENT 발생 !! ◀◀◀◀◀◀◀◀◀◀");
        logger.info("[Req Recv File Event] ※ Event 디렉토리  : [" + dirPath         +"]");
        logger.info("[Req Recv File Event] ※ Event 파일명    : [" + fileName        +"]");
        logger.info("[Req Recv File Event] =========================================================================");
        
        // 디렉토리 구조를 파싱하여 업무구분코드, 대외기관코드, 거래구분그룹 정보를 조회한다.
		// 각 디렉토리명은 다음과같은 규칙으로 정의된다.
        // 기본  ROOT : Property Table에 등록 ...
        // 기본  ROOT 이하
        // --> 2단계 (업무코드/대외기관코드)
        String strBaseDir = BatchDirUtil.getReqRecvRootDir();  //요구수신_Root 기준 디렉토리
        strBaseDir = strBaseDir.replaceAll("\\\\", "/");
        dirPath    = dirPath.replaceAll("\\\\", "/");
        logger.info("※ BaseDir info in DB : [" + strBaseDir        +"]");

        int n = dirPath.indexOf(strBaseDir);
        if (n < 0) {
            throw new Exception("FILE EVENT directory is not match with Base Directory information in DB Table(TSEAIBP02)");
        }

        // 요구수신_Root 기준 디렉토리 이후의 디렉토리 구조를 잘라낸다.
        dirPath = dirPath.substring(n);
        dirPath = dirPath.substring(strBaseDir.length());
        logger.info("※ SubDir removed BaseDir : [" + dirPath        +"]");

        int index1 = (dirPath.charAt(0) == '/')? 1 : 0;
        int index2 = dirPath.indexOf("/", index1+1);

        logger.info("index1="+index1+", index2="+index2);

		//업무구분 디렉토리 설정 (업무구분명_업무구분코드)
        if (index2 < 0) {
            throw new Exception("FILE EVENT directory is not proper. No subdirectory directed releated with Institution");
        } else {
            processCode     = dirPath.substring(index1, index2);
        }
        institutionCode = dirPath.substring(index2+1);

        logger.info("processCode     = " + processCode);

        logger.info("institutionCode = " + institutionCode);

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

		if (bizCodeStartIndex <= 0 || bizCodeStartIndex >= fileName.length()) bizCodeStartIndex = 0;
		if (bizCodeEndIndex   <= 0 || bizCodeEndIndex   >  fileName.length()) bizCodeEndIndex = fileName.length();
		String bizCode = fileName.substring(bizCodeStartIndex, bizCodeEndIndex);
        
		logger.info("[Req Recv File Event] -------------------------------------------------------------------------");
		logger.info("[Req Recv File Event] ■ File Event 파싱 정보");
		logger.info("[Req Recv File Event] - 수신디렉토리: [" + dirPath          +"]");
		logger.info("[Req Recv File Event] - 수신파일명  : [" + fileName         +"]");
		logger.info("[Req Recv File Event] - 업무구분명  : [" + processName      +"] (업무구분코드: "+ processCode     +")");
		logger.info("[Req Recv File Event] - 대외기관명  : [" + institutionName  +"] (대외기관코드: "+ institutionCode +")");
		logger.info("[Req Recv File Event] - 거래구분코드: [" + bizCode          +"]");
		logger.info("[Req Recv File Event] -------------------------------------------------------------------------");


        /*
         * 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().setProcessName(processName);                     // 업무명
        batchMsgDoc.getBatchMsg().getHeader().setProcessType(CommonKeys.PROCESS_REQUEST_RECEIVE); // 업무유형 (요구송신 설정)
        batchMsgDoc.getBatchMsg().getHeader().setInstitutionCode(institutionCode);             // 대외기관코드
        batchMsgDoc.getBatchMsg().getHeader().setInstitutionName(institutionName);             // 대외기관명
        batchMsgDoc.getBatchMsg().getHeader().setFileName(fileName);                           // 원 파일명
        batchMsgDoc.getBatchMsg().getHeader().setBizCode(bizCode);                              // 거래구분코드
        info = SchedulerMessageManager.getInstance().getRecvScheduleInfo(bizCode, processCode, institutionCode);
		if ( info == null ){
			String errMsg = ExceptionUtil.getErrorCode("BECEAISSC016", new String[] {processCode, institutionCode, bizCode});
			throw new Exception(errMsg);	//해당 정보에 대한 스케쥴 정보가 존재하지 않습니다. (업무코드: {1}, 대외기관코드: {2}, 거래구분코드: {3})
		}
    }

    private void callFileMover() throws Exception
    {
		info.setFileName(batchMsgDoc.getBatchMsg().getHeader().getFileName());
		//1. 요구수신 스케쥴러 단계 DB로그를 위한 BatchMsg 객체 생성
		EAIBatchMsgManager.updateBatchMsgWithStageTime(batchMsgDoc, CommonKeys.LAYER_SCHEDULER, CommonKeys.SUB_LAYER_SCHEDULER_QUEUE);  // layer, flowPahse, 시작시간 설정

		//2. 요구수신 디렉토리 설정 (수신_Real/업무구분/대외기관/..)
		//요구수신 기준 디렉토리 --> 배치업무유형코드(ProcessCode) 와 대외기관코드 (InstitutionCode) 로 계산.
		String strPathName = BatchDirUtil.getResponseRealDir();
		if ( strPathName.charAt(strPathName.length()-1) != '/' ) {
			strPathName = strPathName + '/';
		}


		StringBuffer sb = new StringBuffer();
		sb.append(processCode);
		sb.append("/");
		sb.append(institutionCode);
		strPathName = strPathName + sb.toString();
		info.setFilePath(strPathName);


		//3. UUID 설정 및 스케쥴 송수신 시각 설정
		info.setUUID           (batchMsgDoc.getBatchMsg().getHeader().getUUID());
		info.setSubUUID        (batchMsgDoc.getBatchMsg().getBody().getSubUUID());
		info.setStartTime(DatetimeUtil.getCurrentDate() + "000000000");
		info.setEndTime  (DatetimeUtil.getCurrentDate() + "235900000");

		//4. Job_Queue 테이블에 등록
		logger.info("[요구수신 스케쥴러] =========================================================================");
		logger.info("[요구수신 스케쥴러] ■ 요구수신 스케쥴 정보를 Job_Queue 테이블에 추가......");
		int resultCnt = SchedulerMessageManager.getInstance().insertJobToQueue(info);
		logger.info("[요구수신 스케쥴러] ==> 배치 Job_Queue 테이블 INSERT 건수: "+ resultCnt);
		logger.info("[요구수신 스케쥴러] =========================================================================");

    }
    private void closeLog() throws Exception
    {
        // 단계 종료시간을 추가한다.
        batchMsgDoc.getBatchMsg().getBody().setPhaseEndTime(CalendarUtil.getCurrentTimeNoDash());

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

    private void catchException(Exception ex)
    {
        try {
            // 파일로그 처리
            String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAIIFE007");
            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("[Req Recv File Event] ★★★★★ 수신 요청 File Event Listner 예외 처리 중 에러 !! ★★★★★", e);
        }
    }
	@Override
	public BatchDoc clientRequestwithReturn(
			BatchDoc batchDoc) throws Exception {
		return null;
	}
	@Override
	public void clientRequest() throws Exception {
	}

}
