package com.eactive.eai.batch.scheduler;

import java.io.File;

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

public class ScheduleSendProcess {

    // FileLoger
    private static Logger logger = Logger.getLogger(Logger.LOGGER_SCHEDULER);
    private BatchDoc batchMsgDoc;

    public void proc(BatchDoc recvDoc){
    	batchMsgDoc = recvDoc;
    	startLog();
    	try {
			String hdrInfoName = batchMsgDoc.getBatchMsg().getHeader().getHdrInfoName();
    		SchedulerMessageVO vo = getScheduleInfo();
    		if ( vo != null ){
    			vo.setHdrInfoName(hdrInfoName);
    			regJobQueue(vo);
    		} else {
    			discardJob();
    		}
    		closeLog();
		} catch (Exception e) {
			catchException(e);
		}
    }
    private void startLog(){
		batchMsgDoc.getBatchMsg().getHeader().setLayerCode(CommonKeys.LAYER_SCHEDULER);
		batchMsgDoc.getBatchMsg().getBody().setSubLayerCode(CommonKeys.SUB_LAYER_SCHEDULER_QUEUE);
        batchMsgDoc.getBatchMsg().getBody().setPhaseStartTime(CalendarUtil.getCurrentTimeNoDash());
        batchMsgDoc.getBatchMsg().getBody().setPhaseEndTime("");
    }
    
    private SchedulerMessageVO getScheduleInfo() throws Exception
    {
		// 1. inputDoc에서 필요한 값들을 추출한다.
		String bizCode          = batchMsgDoc.getBatchMsg().getHeader().getBizCode();
		String processCode      = batchMsgDoc.getBatchMsg().getHeader().getProcessCode();
		String osidinstidstCode = batchMsgDoc.getBatchMsg().getHeader().getInstitutionCode();
		String renamedFileName  = batchMsgDoc.getBatchMsg().getHeader().getRenamedFileName();
		String renamedDir       = batchMsgDoc.getBatchMsg().getHeader().getFilePath();
		String orgFileName      = batchMsgDoc.getBatchMsg().getHeader().getFileName();
		logger.info("[요구송신 스케쥴러] - UUID            : " + batchMsgDoc.getBatchMsg().getHeader().getUUID());
		logger.info("[요구송신 스케쥴러] - 거래구분코드    : " + bizCode);
		logger.info("[요구송신 스케쥴러] - 업무구분코드    : " + processCode);
		logger.info("[요구송신 스케쥴러] - 대외기관코드    : " + osidinstidstCode);
		logger.info("[요구송신 스케쥴러] - 저장된 디렉토리 : " + renamedDir);
		logger.info("[요구송신 스케쥴러] - 저장된 파일명   : " + renamedFileName);
		logger.info("[요구송신 스케쥴러] - 원 파일명       : " + orgFileName);

		// 2. 전달된 파일명으로 등록된 스케쥴정보를 조회
		return SchedulerMessageManager.getInstance().getScheduleInfo(bizCode, processCode, osidinstidstCode);

    }
    
    private void regJobQueue(SchedulerMessageVO scheduleInfo ) throws Exception
    {
		logger.info("[요구송신 스케쥴러] - 스케쥴코드    : " + scheduleInfo.getScheduleCode() 
		             + "(" + scheduleInfo.getStartTime() + "~" + scheduleInfo.getEndTime());

		// 3.BATCH작업 요청메시지ID 및 스케쥴 송수신 시각 설정
		//  - 요구송신의 경우 UUID는 FileEventListener로부터 전달된다.
		scheduleInfo.setUUID           (batchMsgDoc.getBatchMsg().getHeader().getUUID());
		scheduleInfo.setSubUUID        (batchMsgDoc.getBatchMsg().getBody().getSubUUID());
		scheduleInfo.setFilePath       (batchMsgDoc.getBatchMsg().getHeader().getFilePath());
		scheduleInfo.setFileName       (batchMsgDoc.getBatchMsg().getHeader().getFileName());
		scheduleInfo.setRenamedFileName(batchMsgDoc.getBatchMsg().getHeader().getRenamedFileName());
		
    	//int startDelay = scheduleInfo.getStartDelayDays();
    	int endDelay   = scheduleInfo.getEndDelayDays();
    	if (!scheduleInfo.getStartTime().equals("")) scheduleInfo.setStartTime(DatetimeUtil.getCurrentDate() + scheduleInfo.getStartTime() +"00" + "000");
    	// 송신 시작 지연 일수 --> 기능 삭제
    	//if (!scheduleInfo.getStartTime().equals("")) scheduleInfo.setStartTime(DatetimeUtil.getDayAddedDate( DatetimeUtil.getCurrentDate(), startDelay ) + scheduleInfo.getStartTime() +"00" + "00");
		if (!scheduleInfo.getEndTime()  .equals("")) scheduleInfo.setEndTime  (DatetimeUtil.getDayAddedDate( DatetimeUtil.getCurrentDate(), endDelay ) + scheduleInfo.getEndTime()   +"00" + "000");


		// 4.JOB QUEUE 테이블에 등록
		int resultCnt = SchedulerMessageManager.getInstance().insertJobToQueue(scheduleInfo);
		logger.info("[요구송신 스케쥴러] ==> 배치 JOB QUEUE 테이블 INSERT 건수: "+ resultCnt);

		// 5. DB로그를 위해서 조회정보를 batchMsgDoc에 세팅
		batchMsgDoc.getBatchMsg().getHeader().setProcessType(scheduleInfo.getProcessType());        //업무유형코드
		batchMsgDoc.getBatchMsg().getHeader().setScheduleCode(scheduleInfo.getScheduleCode());      //스케쥴등록ID
		batchMsgDoc.getBatchMsg().getHeader().setJobCode(scheduleInfo.getJobCode());                //Job 코드
		batchMsgDoc.getBatchMsg().getHeader().setScheduleSTime(scheduleInfo.getStartTime());        //전송 시작 시각
		batchMsgDoc.getBatchMsg().getHeader().setScheduleETime(scheduleInfo.getEndTime());          //전송 종료 시각

    }
    
    private void discardJob() throws Exception
    {
		/* 1.스케쥴 등록이 되어 있지 않은 파일에 대한 처리
		 *   - FileEvent로부터 전달된 파일 중 스케쥴이 등록되어 있지 않은 파일은 Error 디렉토리로 옮긴다.
		 *   - 에러 디렉토리로 전송 중 발생하는 에러는 더 이상 상위로 전파하지 않고 내부 처리한다.
		 *   - 즉, 에러 디렉토리 전송 중 에러는 전체 Flow에 영향을 미치치 않는다.
		 */
		String bizCode          = batchMsgDoc.getBatchMsg().getHeader().getBizCode();
		String processCode      = batchMsgDoc.getBatchMsg().getHeader().getProcessCode();
		String osidinstidstCode = batchMsgDoc.getBatchMsg().getHeader().getInstitutionCode();
		String renamedFileName  = batchMsgDoc.getBatchMsg().getHeader().getRenamedFileName();
		try {
			String archDir  = batchMsgDoc.getBatchMsg().getHeader().getFilePath();
			String errorDir = batchMsgDoc.getBatchMsg().getHeader().getFileErrorPath();
			File archFile  = new File(archDir   +"/"+ renamedFileName);
			File errorFile = new File(errorDir  +"/"+ renamedFileName);

			//Arch 디렉토리에서 Error 디렉토리로 파일 이동
			logger.info("[요구송신 스케쥴러] ★ 스케쥴 미등록 파일 이동 (송신_Arch -> 송신_Error)");
			logger.info("[요구송신 스케쥴러] - Arch  디렉토리: ["+ archDir  +"/"+ renamedFileName +"] (exists: "+ archFile.exists()  +")");
			logger.info("[요구송신 스케쥴러] - Error 디렉토리: ["+ errorDir +"/"+ renamedFileName +"] (exists: "+ errorFile.exists() +")");

			boolean isSuccessMoveFile = archFile.renameTo(errorFile);
			if (!isSuccessMoveFile) {
				String errMsg = ExceptionUtil.getErrorCode("BECEAISSC026", new String[] {archFile.getAbsolutePath(), errorFile.getAbsolutePath()});
				throw new Exception(errMsg); //요구송신 데이터파일을 송신_Arch 디렉토리({1})에서 송신_Error 디렉토리({2})로 이동시 실패하였습니다.
			}

		} catch (Exception e) {
			logger.error("[요구송신 스케쥴러] ★★★★★ 스케쥴 미등록 파일 이동 중 에러 !! ★★★★★", e);
		}

		String errMsg = ExceptionUtil.getErrorCode("BECEAISSC016", new String[] {processCode, osidinstidstCode, bizCode, batchMsgDoc.getBatchMsg().getHeader().getHdrInfoName().substring(27, 37)});
		throw new Exception(errMsg);	//해당 정보에 대한 스케쥴 정보가 존재하지 않습니다. (업무코드: {1}, 대외기관코드: {2}, 거래구분코드: {3})
    }

    private void closeLog() throws Exception
    {
		batchMsgDoc.getBatchMsg().getBody().setPhaseEndTime(CalendarUtil.getCurrentTimeNoDash());
        LogUtil.setLog(batchMsgDoc);

		//요구송신 스케쥴러에 의해 설정된 값을 Master 로그에 Update.
		LogUtil.updateLogMaster(batchMsgDoc);
    }

    /* 예외 처리를 위한 노드 */
    private void catchException(Exception ex)
    {
		logger.error("[요구송신 스케쥴러] ★★★★★ 예외 발생 !! ★★★★★", ex);
        try {
            // 파일로그 처리
			String errMsg = ExceptionUtil.getErrorCode(ex, "BECEAISSC017");
            logger.error(errMsg, ex);  //Scheduler Processor JPD 에서 에서 오류가 발생하였습니다.

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

        } catch (Exception e) {
            logger.error("[요구송신 스케쥴러] ★★★★★ 예외 처리 중 에러 !! ★★★★★", e);
        }
    }

}
