package com.eactive.eai.rms.bat.web.eims;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.eactive.eai.common.util.SystemUtil;
import com.eactive.eai.rms.bat.util.EAIBatchResourceValidationService;
import com.eactive.eai.rms.bat.web.eims.vo.BatInterfaceVo;
import com.eactive.eai.rms.bat.web.eims.vo.BatScheduleSubVo;
import com.eactive.eai.rms.bat.web.eims.vo.BatScheduleVo;
import com.eactive.eai.rms.bat.web.eims.vo.DbAdapterVo;
import com.eactive.eai.rms.bat.web.eims.vo.FileAdapterVo;
import com.eactive.eai.rms.common.base.OnlBaseService;

@Service("eimsBatService")
public class EIMSBatService extends OnlBaseService {
 
	private static final Logger logger = Logger.getLogger(EIMSBatService.class);
	
	@Autowired
	@Qualifier("eimsBatDao")
	private EIMSBatDao dao;

	@Autowired
	private EAIBatchResourceValidationService batchValidationService;
	
	private static final String DD_POST_DBIN = "DBIN"; //송신 SND SRC
	private static final String DD_POST_DBOT = "DBOT"; //수신 RCV TGT
	
	private static final String FF_POST_FNIN01 = "FNIN01"; //송신 SND SRC
	private static final String FF_POST_FNOT01 = "FNOT01"; //수신 RCV TGT	
	
//	private static final String DD_POST_FNOT = "FNOT"; //수신 RCV TGT
//	private static final String DD_POST_FNIN = "FNIN"; //송신 SND SRC
	
	private static final String SCHE_ID_DD_D_T = "U_#_DD_D_T_"; //DD스케쥴
	private static final String SCHE_ID_FF_D_F = "U_#_FF_D_F_"; //FF스케쥴
	
	private static final String TRNSRSLTRFLCTYN_Y = "Y"; //DD스케쥴
	
	private static final String COMMITUNITCNT = "1000";
	
	/**
	 * Transactional
	 * infCRUD Update 임시 제거 => 항상 Delete&Create
	 */
	public void insertBatRegister(HashMap<String, String> mergeMap) throws Exception {

		String batInterfaceId = mergeMap.get(EIMSBatConstants.INTFID);
		String userId = mergeMap.get(EIMSBatConstants.AUTHORID);
		String infCRUD = "C"; // 

		// 인터페이스 존재유무에 따라 Update Create 분기
		boolean isIntfid = isIntfid04(batInterfaceId);
		if (isIntfid) 	{ infCRUD = "U"; }
		else 			{ infCRUD = "C"; }
		
		mergeMap.put(EIMSBatConstants.INFCRUD , infCRUD);	
		logger.debug("[MERGE-MAP] BATCHTYPE=" + mergeMap.get(EIMSBatConstants.BATCHTYPE) + ", mergeMap=" + mergeMap);
		
		logger.debug("인터페이스 등록 START");
		makeIntfidRegister(batInterfaceId, userId, mergeMap);
		
		logger.debug("아답터&인터페이스 등록 START");				
		makeAdaptrRegister(batInterfaceId, userId, mergeMap);
		
		logger.info("인터페이스 스케쥴 등록 START");						
		makeScheRegister(batInterfaceId, userId, mergeMap);
		
	}
	
	public void deleteBatRegister(String intfId, String batchType) throws Exception {
		
		try {
			
			if(batchType.equalsIgnoreCase("File") || batchType.equalsIgnoreCase("FF")) {
				dao.deleteAdpterTSEAIEA05(intfId); // EA05
			} else {
				dao.deleteAdpterTSEAIEA03(intfId); // EA03
			}
			dao.deleteSchedule(intfId);  // ES07, ES09 
			dao.deleteInterface(intfId); // EA04

		} catch (Exception e) {
			throw new Exception("인터페이스 삭제 실패 : " + e.getMessage());
		}

	}
	
	private boolean isIntfid04(String intfId) throws Exception {

		int rlt = dao.selectIntfidCheck(intfId);
		logger.debug("selectIntfidCheck : " + rlt);

		if (rlt > 0) {
			return true;
		} else {
			return false;
		}
	}	
	
	protected void makeIntfidRegister(String intfId, String userId, HashMap<String, String> mergeMap) throws Exception {

		String applcd = mergeMap.get(EIMSBatConstants.APPCD);
		
		if (applcd == null || applcd.length() != 3) {
			logger.error("[ERROR] Invalid ApplCd: " + applcd + "]");
			throw new Exception("[ERROR] Invalid ApplCd: " + applcd + "]");
		}

		String workGrpCd = dao.selectWorkGrpcd(applcd);
		
		if (workGrpCd != null && workGrpCd.length() > 0) {
			// 인터페이스등록은 송신기준 업무구분으로 등록됨 (APP코드 = 업무구분코드)
			// 어플리케이션(내부)코드로 EAI배치에서 사용하는 내부코로 매핑 하여 업무구분 코드를 가져옴
			mergeMap.put(EIMSBatConstants.WORKGRPCD, workGrpCd);
			logger.debug("selectWorkGrpcdworkGrpCd=" + workGrpCd + ",applcd=" + applcd);
		} else {
			logger.error("workGrpCd is Empty. workGrpCd=" + workGrpCd + ",applcd=" + applcd);
			throw new Exception("인터페이스 오류[인터페이스ID=" + intfId + "] workGrpCd is Empty. workGrpCd=" + workGrpCd + ",applcd=" + applcd);
		}
		
		BatInterfaceVo intfVo = new BatInterfaceVo();
		intfVo.setAllInf(mergeMap);
		
		if(dao.selectIntfidCheck(intfId) == 0) {
			dao.insertIntfidRegister(intfVo);
		} else {
			dao.updateIntfidRegister(intfVo);
		}
		
	}
	
	//** 2-1.  인터페이스등록여부 체크 / 인터페이스 아이디로 매핑된 아덥터 여부 체크
	//** 3-1. 인터페이스 아이디로 인터페이스 여부 체크 및 송신 및 수신 어댑터 존재 여부 체크
	protected void makeAdaptrRegister(String intfId, String userId, HashMap<String,String> mergeMap) throws Exception {
		
		//인터테이스등록시 어댑터 등록 안함 (기등록된 어댑터가 있으면 매핑해야함 단, 다른 인터페이스 아이디가 있으면 오류로 돌려 보냄)
		//** 어댑터 조회 확인 (결과값 어댑터코드 및 인터페이스 ID)
		String infCRUD = mergeMap.get(EIMSBatConstants.INFCRUD);
		String batchType = mergeMap.get(EIMSBatConstants.BATCHTYPE);
		String srcSystemCd = mergeMap.get(EIMSBatConstants.SRCBZSYSTEMCD);
		String tgtSystemCd = mergeMap.get(EIMSBatConstants.TGTBZSYSTEMCD);
		
		String srcWorkGrpCd = dao.selectWorkGrpcd(mergeMap.get(EIMSBatConstants.SRCAPPCD));
		String tgtWorkGrpCd = dao.selectWorkGrpcd(mergeMap.get(EIMSBatConstants.TGTAPPCD));
		
		// 환경구분값 가져오기 (O:운영, S:테스트, D:개발)
		String envrdvsncd = SystemUtil.getSysOperEvirnDstcd();
		
		if ("DD".equals(batchType)) { // DBToDB 신규등록
			mergeDDAdaptrRegister(srcWorkGrpCd, tgtWorkGrpCd, srcSystemCd, tgtSystemCd, envrdvsncd, mergeMap);
		}

		if ("FF".equals(batchType)) { // FileToFile 신규등록
			mergeFFAdaptrRegister(srcWorkGrpCd, tgtWorkGrpCd, srcSystemCd, tgtSystemCd, envrdvsncd, mergeMap);
		}
		
	}	
	
	private void deleteAdaptrRegister(String intfId, String batchType) throws Exception {
		
		if(batchType.equals("DD")) {
			dao.deleteAdpterTSEAIEA03(intfId);
		} else if (batchType.equals("FF")) {
			dao.deleteAdpterTSEAIEA05(intfId);
		}
		
	}

	private void mergeDDAdaptrRegister(String srcWorkGrpCd, String tgtWorkGrpCd, String srcSystemCd, String tgtSystemCd, String envrdvsncd, HashMap<String,String> mergeMap) throws Exception{

		/**
		 * 송신부 처리 SRC
		 */
		String srcAdapCd = srcSystemCd.trim() + DD_POST_DBIN + "01";	
		String srcNextAdptrCdSeq = "1";
		
		if(batchValidationService.isAdapterNotExist(srcAdapCd)) {
			throw new Exception("["+srcAdapCd+"] 어댑터가 개발 모니터링 시스템에 등록되어 있지 않습니다. 배치 관리자에게 문의하십시오.");
		}
		
		try {
			DbAdapterVo srcDbAdapterVo = new DbAdapterVo();
			srcDbAdapterVo.setAdptrcd(srcAdapCd);
			srcDbAdapterVo.setAdptrcdseq(srcNextAdptrCdSeq);
			srcDbAdapterVo.setIntfid(mergeMap.get(EIMSBatConstants.INTFID));
			srcDbAdapterVo.setSqlname(mergeMap.get(EIMSBatConstants.INTFNAME));
			srcDbAdapterVo.setSqlnamedesc(mergeMap.get(EIMSBatConstants.INTFDESC));
			srcDbAdapterVo.setDbsql(mergeMap.get(EIMSBatConstants.SRCDBEXTRACTQUERY).replace(";", ""));
			srcDbAdapterVo.setTxcommitunitcnt(COMMITUNITCNT);
			srcDbAdapterVo.setSelectunitcnt(COMMITUNITCNT);
			srcDbAdapterVo.setDbeventwhere(EIMSBatConstants.DBEVENTWHERE_SND); // 송신(1), 수신(2), 결과반영(3)
			srcDbAdapterVo.setWorkGrpCd(srcWorkGrpCd);

			if(dao.isInterfaceSubExist(mergeMap.get(EIMSBatConstants.INTFID), srcNextAdptrCdSeq)) {
				dao.updateAdaptr03Register(srcDbAdapterVo);
			} else {
				dao.insertAdaptr03Register(srcDbAdapterVo);
			}
		} catch(Exception e) {
			logger.error(e);					
			throw new Exception("["+mergeMap.get(EIMSBatConstants.INTFID)+"] 소스 인터페이스 상세 등록 실패");
		}

		/**
		 * 수신부 처리 TGT
		 */
		String tgtAdapCd = tgtSystemCd.trim() + DD_POST_DBOT + "01";
		String tgtNextAdptrCdSeq = "2";
		
		if(batchValidationService.isAdapterNotExist(tgtAdapCd)) {
			throw new Exception("["+tgtAdapCd+"] 어댑터가 개발 모니터링 시스템에 등록되어 있지 않습니다. 배치 관리자에게 문의하십시오.");
		}
		
		try {
			DbAdapterVo tgtDbAdapterVo = new DbAdapterVo();
			tgtDbAdapterVo.setAdptrcd(tgtAdapCd);
			tgtDbAdapterVo.setAdptrcdseq(tgtNextAdptrCdSeq);
			tgtDbAdapterVo.setIntfid(mergeMap.get(EIMSBatConstants.INTFID));
			tgtDbAdapterVo.setSqlname(mergeMap.get(EIMSBatConstants.INTFNAME));
			tgtDbAdapterVo.setSqlnamedesc(mergeMap.get(EIMSBatConstants.INTFDESC));
			tgtDbAdapterVo.setDbsql(mergeMap.get(EIMSBatConstants.TGTDBLOADQUERY).replace(";", ""));
			tgtDbAdapterVo.setTxcommitunitcnt(COMMITUNITCNT);
			tgtDbAdapterVo.setSelectunitcnt(COMMITUNITCNT);
			tgtDbAdapterVo.setDbeventwhere(EIMSBatConstants.DBEVENTWHERE_RCV); // 송신(1), 수신(2), 결과반영(3)
			tgtDbAdapterVo.setWorkGrpCd(tgtWorkGrpCd);
			
			if(dao.isInterfaceSubExist(mergeMap.get(EIMSBatConstants.INTFID), tgtNextAdptrCdSeq)) {
				dao.updateAdaptr03Register(tgtDbAdapterVo);
			} else {
				dao.insertAdaptr03Register(tgtDbAdapterVo);
			}
		}catch(Exception e) {
			logger.error(e);					
			throw new Exception("["+mergeMap.get(EIMSBatConstants.INTFID)+"] 타겟 인터페이스 상세 등록 실패");		
		}
			
		/**
		 * 수신부 DB처리 결과반영 RLT
		 */
		String rltAdapCd = srcSystemCd.trim() + DD_POST_DBOT + "01";
		String rltNextAdptrCdSeq = "3";
		
		if(batchValidationService.isAdapterNotExist(rltAdapCd)) {
			throw new Exception("["+rltAdapCd+"] 어댑터가 개발 모니터링 시스템에 등록되어 있지 않습니다. 배치 관리자에게 문의하십시오.");
		}
		
		//** DB어댑터 상세 등록(송신)
		try {
			DbAdapterVo rltDbAdapterVo = new DbAdapterVo();
			rltDbAdapterVo.setAdptrcd(rltAdapCd);
			rltDbAdapterVo.setAdptrcdseq(rltNextAdptrCdSeq);
			rltDbAdapterVo.setIntfid(mergeMap.get(EIMSBatConstants.INTFID));
			rltDbAdapterVo.setSqlname(mergeMap.get(EIMSBatConstants.INTFNAME));
			rltDbAdapterVo.setSqlnamedesc(mergeMap.get(EIMSBatConstants.INTFDESC));
			rltDbAdapterVo.setDbsql(mergeMap.get(EIMSBatConstants.SRCDBRSLTRFLCTQUERY).replace(";", ""));
			rltDbAdapterVo.setTxcommitunitcnt(COMMITUNITCNT);
			rltDbAdapterVo.setSelectunitcnt(COMMITUNITCNT);
			rltDbAdapterVo.setDbeventwhere(EIMSBatConstants.DBEVENTWHERE_SNDFLAG); // 송신(1), 수신(2), 결과반영(3)
			rltDbAdapterVo.setWorkGrpCd(srcWorkGrpCd);	
			rltDbAdapterVo.setDelyn(mergeMap.get(EIMSBatConstants.TRNSRSLTRFLCTYN));
					
			if(dao.isInterfaceSubExist(mergeMap.get(EIMSBatConstants.INTFID), rltNextAdptrCdSeq)) {
				dao.updateAdaptr03Register(rltDbAdapterVo);
			} else {
				dao.insertAdaptr03Register(rltDbAdapterVo);
			}
		}catch(Exception e) {
			logger.error(e);					
			throw new Exception("["+mergeMap.get(EIMSBatConstants.INTFID)+"] 소스결과반영 인터페이스 상세 등록 실패");		
		}
		
		try {
			BatInterfaceVo intfVo = new BatInterfaceVo();
			intfVo.setIntfid(mergeMap.get(EIMSBatConstants.INTFID));
			intfVo.setSndadptrcd(srcAdapCd);
			intfVo.setSndadptrcdseq("1");
			
			dao.updateSndAdptToIntf(intfVo);
		} catch(Exception e) {
			logger.error(e);					
			throw new Exception("[DD] 인터페이스 시컨스 아답터 업데이트  오류-[srcAdapCd="+ srcAdapCd+",srcNextAdptrCdSeq="+srcNextAdptrCdSeq + "]");		
		}
		
	}
	
	private void updateDDAdaptrRegister(String srcWorkGrpCd, String tgtWorkGrpCd, String srcSystemCd, String tgtSystemCd, String envrdvsncd, HashMap<String,String> mergeMap) throws Exception{
					
		String intfId = mergeMap.get(EIMSBatConstants.INTFID);
		
		List<Map<String, String>> adptList;
		Map<String, String> rltMap;
				
		/**
		 * 송신부 처리 SRC
		 */
		//** 송신어댑터 업데이트				
		String srcAdptrCd, srcAdptrCdSeq;
		
		//** 인터페이스id로 어댑터정보 가져옴
		adptList = dao.selectListAdptrCheck(srcWorkGrpCd,intfId,EIMSBatConstants.SNDRCVKIND_SND, null);
		if( adptList.isEmpty() ) {
			logger.error("AdaptrRegister[DD]-U.SRC adptrCd is exist. intfId="+intfId+",srcWorkGrpCd="+srcWorkGrpCd);
			throw new Exception("AdaptrRegister[DD]-U.SRC adptrCd is exist. intfId="+intfId+",srcWorkGrpCd="+srcWorkGrpCd);
		}
		
		rltMap = adptList.get(0);		
		srcAdptrCd = rltMap.get("ADPTRCD");
		srcAdptrCdSeq = String.valueOf(rltMap.get("ADPTRCDSEQ"));
		
		try {
			//** 송신 상세 어댑터 수정 TSEAIEA03 
			DbAdapterVo srcDbAdapterVo = new DbAdapterVo();
			srcDbAdapterVo.setAdptrcd(srcAdptrCd);
//			srcDbAdapterVo.setAdptrcdseq(srcAdptrCdSeq);
			srcDbAdapterVo.setIntfid(intfId);
			srcDbAdapterVo.setTxcommitunitcnt(COMMITUNITCNT );
			srcDbAdapterVo.setSelectunitcnt(COMMITUNITCNT );
			srcDbAdapterVo.setSqlname(mergeMap.get(EIMSBatConstants.INTFNAME));
			srcDbAdapterVo.setSqlnamedesc(mergeMap.get(EIMSBatConstants.INTFDESC));
			srcDbAdapterVo.setDbsql(mergeMap.get(EIMSBatConstants.SRCDBEXTRACTQUERY).replace(";", ""));
			srcDbAdapterVo.setWorkGrpCd(srcWorkGrpCd);
			dao.updateAdaptr03Register(srcDbAdapterVo);
		}catch(Exception e) {
			logger.error(e);					
			throw new Exception("AdaptrRegister[DD]-U.SRC updateAdaptr03Register Fail.");		
		}
		
		/**
		 * 수신부 처리 TGT
		 */
		String tgtAdptrCd, tgtAdptrCdSeq;
		
		//** 인터페이스id로 어댑터정보 가져옴
		adptList = dao.selectListAdptrCheck(tgtWorkGrpCd,intfId,EIMSBatConstants.SNDRCVKIND_RCV, EIMSBatConstants.DBEVENTWHERE_RCV);
		if( adptList.isEmpty() ) {
			logger.error("AdaptrRegister[DD]-U.TGT adptrCd is exist. intfId="+intfId+",tgtWorkGrpCd="+tgtWorkGrpCd);
			throw new Exception("AdaptrRegister[DD]-U.TGT adptrCd is exist. intfId="+intfId+",tgtWorkGrpCd="+tgtWorkGrpCd);
		}
		
		rltMap = adptList.get(0);		
		tgtAdptrCd = rltMap.get("ADPTRCD");
		tgtAdptrCdSeq = String.valueOf(rltMap.get("ADPTRCDSEQ"));
		
		try {
			//** 송신 상세 어댑터 수정 TSEAIEA03 
			DbAdapterVo tgtDbAdapterVo = new DbAdapterVo();
			tgtDbAdapterVo.setAdptrcd(tgtAdptrCd);
//			tgtDbAdapterVo.setAdptrcdseq(tgtAdptrCdSeq);
			tgtDbAdapterVo.setIntfid(intfId);
			tgtDbAdapterVo.setTxcommitunitcnt(COMMITUNITCNT );
			tgtDbAdapterVo.setSelectunitcnt(COMMITUNITCNT );
			tgtDbAdapterVo.setSqlname(mergeMap.get(EIMSBatConstants.INTFNAME));
			tgtDbAdapterVo.setSqlnamedesc(mergeMap.get(EIMSBatConstants.INTFDESC));
			tgtDbAdapterVo.setDbsql(mergeMap.get(EIMSBatConstants.TGTDBLOADQUERY).replace(";", ""));
			tgtDbAdapterVo.setWorkGrpCd(tgtWorkGrpCd);
			dao.updateAdaptr03Register(tgtDbAdapterVo);
		}catch(Exception e) {
			logger.error(e);					
			throw new Exception("AdaptrRegister[DD]-U.TGT updateAdaptr03Register Fail.");		
		}
		
		/**
		 * 수신부 DB처리 결과 처리 RLT
		 */
		String rltAdapCd, rltAdptrCdSeq;
		
		//** 인터페이스id로 어댑터정보 가져옴
		adptList = dao.selectListAdptrCheck(srcWorkGrpCd,intfId,EIMSBatConstants.SNDRCVKIND_RCV, EIMSBatConstants.DBEVENTWHERE_SNDFLAG);
		if( adptList.isEmpty() ) {
			logger.error("AdaptrRegister[DD]-U.RLT adptrCd is exist. intfId="+intfId+",tgtWorkGrpCd="+tgtWorkGrpCd);
			throw new Exception("AdaptrRegister[DD]-U.RLT adptrCd is exist. intfId="+intfId+",tgtWorkGrpCd="+tgtWorkGrpCd);
		}
		
		rltMap = adptList.get(0);		
		rltAdapCd = rltMap.get("ADPTRCD");
		rltAdptrCdSeq = String.valueOf(rltMap.get("ADPTRCDSEQ"));
		
					
		//** DB어댑터 상세 등록(송신)
		try {
			//** 송신 상세 어댑터 등록 TSEAIEA03 
			DbAdapterVo rltDbAdapterVo = new DbAdapterVo();
			rltDbAdapterVo.setAdptrcd(rltAdapCd);
//			rltDbAdapterVo.setAdptrcdseq(rltAdptrCdSeq);
			rltDbAdapterVo.setIntfid(intfId);
			rltDbAdapterVo.setSqlname(mergeMap.get(EIMSBatConstants.INTFNAME));
			rltDbAdapterVo.setSqlnamedesc(mergeMap.get(EIMSBatConstants.INTFDESC));
			rltDbAdapterVo.setDbsql(mergeMap.get(EIMSBatConstants.SRCDBRSLTRFLCTQUERY).replace(";", ""));	
			
			rltDbAdapterVo.setDelyn(mergeMap.get(EIMSBatConstants.TRNSRSLTRFLCTYN));
			rltDbAdapterVo.setWorkGrpCd(srcWorkGrpCd);
			dao.updateAdaptr03Register(rltDbAdapterVo);		
			
		}catch(Exception e) {
			logger.error(e);					
			throw new Exception("AdaptrRegister[DD]-U.RLT updateAdaptr03Register Fail.");		
		}
		
	}
	
	private void mergeFFAdaptrRegister(String srcWorkGrpCd, String tgtWorkGrpCd, String srcSystemCd, String tgtSystemCd, String envrdvsncd, HashMap<String,String> mergeMap) throws Exception{
			
		/**
		 * 송신부 처리 SRC
		 */
		String srcAdapCd = srcSystemCd.trim() + FF_POST_FNIN01;		
		String srcNextAdptrCdSeq = "1";
		
		if(batchValidationService.isAdapterNotExist(srcAdapCd)) {
			throw new Exception("["+srcAdapCd+"] 어댑터가 개발 모니터링 시스템에 등록되어 있지 않습니다. 배치 관리자에게 문의하십시오.");
		}
		
		try {
			//** 송신 상세 어댑터 등록 TSEAIEA05 
			FileAdapterVo srcFileAdapterVo = new FileAdapterVo();
			srcFileAdapterVo.setAdptrcd(srcAdapCd);
			srcFileAdapterVo.setAdptrcdseq(srcNextAdptrCdSeq);
			srcFileAdapterVo.setIntfid(mergeMap.get(EIMSBatConstants.INTFID));
			srcFileAdapterVo.setFtpname(mergeMap.get(EIMSBatConstants.INTFNAME));
//			srcFileAdapterVo.setFtpnamedesc(srcFtpHost);
//			srcFileAdapterVo.setFtphostname(srcFtpHost);			
//			srcFileAdapterVo.setRmtsevrftpportnoname(srcFtpPort);			
//			srcFileAdapterVo.setRmtsevrftpuid(srcFtpId);
			srcFileAdapterVo.setFtparchivedir(mergeMap.get(EIMSBatConstants.SRCFILEPATH));
			srcFileAdapterVo.setFtpstorefilepattern(mergeMap.get(EIMSBatConstants.SRCFILENM));
			srcFileAdapterVo.setWorkGrpCd(srcWorkGrpCd);
			
			//추가 기능 설정없음(체크파일:스케쥴시필요, 백업디렉토리)
			String eventYn = mergeMap.get(EIMSBatConstants.EVENTCALLVAL);
			if(EIMSBatConstants.EVENTCALLVAL_SCHED.equals(eventYn)) {
				srcFileAdapterVo.setCheckname("chk");
				srcFileAdapterVo.setFtpcheckdir(mergeMap.get(EIMSBatConstants.SRCFILEPATH));
				srcFileAdapterVo.setNextoption("1");
			}
			dao.mergeSubFileAdaptr(srcFileAdapterVo);
		} catch (Exception e) {
			logger.error(e);
			throw new Exception("["+mergeMap.get(EIMSBatConstants.INTFID)+"] 소스 인터페이스 상세 등록 실패");
		}
		
		/**
		 * 수신부 처리 TGT
		 */
		String tgtAdapCd = tgtSystemCd.trim() + FF_POST_FNOT01;
		String tgtNextAdptrCdSeq = "2";
		
		if(batchValidationService.isAdapterNotExist(tgtAdapCd)) {
			throw new Exception("["+tgtAdapCd+"] 어댑터가 개발 모니터링 시스템에 등록되어 있지 않습니다. 배치 관리자에게 문의하십시오.");
		}
		
		try {
			// ** 수신 상세 어댑터 등록 TSEAIEA05
			FileAdapterVo tgtFileAdapterVo = new FileAdapterVo();
			tgtFileAdapterVo.setAdptrcd(tgtAdapCd);
			tgtFileAdapterVo.setAdptrcdseq(tgtNextAdptrCdSeq);
			tgtFileAdapterVo.setIntfid(mergeMap.get(EIMSBatConstants.INTFID));
			tgtFileAdapterVo.setFtpname(mergeMap.get(EIMSBatConstants.INTFNAME));
//			tgtFileAdapterVo.setFtpnamedesc(tgtFtpHost);
//			tgtFileAdapterVo.setFtphostname(tgtFtpHost);
//			tgtFileAdapterVo.setRmtsevrftpportnoname(tgtFtpPort);
//			tgtFileAdapterVo.setRmtsevrftpuid(tgtFtpId);
			tgtFileAdapterVo.setFtparchivedir(mergeMap.get(EIMSBatConstants.TGTFILEPATH));
//			tgtFileAdapterVo.setFtpstorefilepattern(mergeMap.get(EIMSBatParserKey.SRCFILENM));
			tgtFileAdapterVo.setWorkGrpCd(tgtWorkGrpCd);
			String eventYn = mergeMap.get(EIMSBatConstants.EVENTCALLVAL);
			if (EIMSBatConstants.EVENTCALLVAL_SCHED.equals(eventYn) || EIMSBatConstants.EVENTCALLVAL_EVENT.equals(eventYn)) {
				tgtFileAdapterVo.setCheckname("chk");
				tgtFileAdapterVo.setFtpcheckdir(mergeMap.get(EIMSBatConstants.TGTFILEPATH));
				tgtFileAdapterVo.setNextoption("1");
			}
			dao.mergeSubFileAdaptr(tgtFileAdapterVo);
		} catch (Exception e) {
			logger.error(e);
			throw new Exception("["+mergeMap.get(EIMSBatConstants.INTFID)+"] 타겟 인터페이스 상세 등록 실패");
		}
		
		try {
			BatInterfaceVo intfVo = new BatInterfaceVo();
			intfVo.setIntfid(mergeMap.get(EIMSBatConstants.INTFID));
			intfVo.setSndadptrcd(srcAdapCd);
			intfVo.setSndadptrcdseq("1");
			
			dao.updateSndAdptToIntf(intfVo);
		} catch(Exception e) {
			logger.error(e);
			throw new Exception("[DD] 인터페이스 SEND어댑터 업데이트  오류-[srcAdapCd="+ srcAdapCd+",srcNextAdptrCdSeq="+srcNextAdptrCdSeq + "]");		
		}

	}
	
	/**
	 * FileToFile 수정등록
	 */
	private void updateFFAdaptrRegister(String srcWorkGrpCd, String tgtWorkGrpCd, String srcSystemCd, String tgtSystemCd, String envrdvsncd, HashMap<String,String> mergeMap) throws Exception{
				
		String intfId = mergeMap.get(EIMSBatConstants.INTFID);

		List<Map<String, String>> adptList;
		Map<String, String> rltMap;
		
		/**
		 * 송신부 처리 SRC FileToFile 수정등록
		 */
		String srcAdptrCd, srcAdptrCdSeq;
		
		//** 인터페이스id로 어댑터정보 가져옴
		adptList = dao.selectListAdptrCheck(srcWorkGrpCd,intfId,EIMSBatConstants.SNDRCVKIND_SND, null);
		if( adptList.isEmpty() ) {
			logger.error("AdaptrRegister[FF]-U.SRC adptrCd is exist. intfId="+intfId+",srcWorkGrpCd="+srcWorkGrpCd);
			throw new Exception("AdaptrRegister[FF]-U.SRC adptrCd is exist. intfId="+intfId+",srcWorkGrpCd="+srcWorkGrpCd);
		}
		
		rltMap = adptList.get(0);
		srcAdptrCd = rltMap.get("ADPTRCD");
		srcAdptrCdSeq = String.valueOf(rltMap.get("ADPTRCDSEQ"));
			
		
		//** File 어댑터 상세 등록(송신)
		try {
			//** 송신 상세 어댑터 등록 TSEAIEA05 
			FileAdapterVo srcFileAdapterVo = new FileAdapterVo();
			srcFileAdapterVo.setAdptrcd(srcAdptrCd);
//			srcFileAdapterVo.setAdptrcdseq(srcAdptrCdSeq);
			srcFileAdapterVo.setIntfid(intfId);
			srcFileAdapterVo.setFtpname(mergeMap.get(EIMSBatConstants.INTFNAME));
			srcFileAdapterVo.setFtparchivedir(mergeMap.get(EIMSBatConstants.SRCFILEPATH));
			srcFileAdapterVo.setFtpstorefilepattern(mergeMap.get(EIMSBatConstants.SRCFILENM));
			srcFileAdapterVo.setWorkGrpCd(srcWorkGrpCd);
			//추가 기능 설정없음(체크파일:스케쥴시필요, 백업디렉토리)
			String eventYn = mergeMap.get(EIMSBatConstants.EVENTCALLVAL);
			if(EIMSBatConstants.EVENTCALLVAL_SCHED.equals(eventYn)) {
				srcFileAdapterVo.setCheckname("chk");
				srcFileAdapterVo.setFtpcheckdir(mergeMap.get(EIMSBatConstants.SRCFILEPATH));
				srcFileAdapterVo.setNextoption("1");
			}
			dao.updateSubFileAdaptr(srcFileAdapterVo);
		}catch(Exception e) {
			logger.error(e);					
			throw new Exception("AdaptrRegister[FF]-U.SRC updateSubFileAdaptr Fail.");		
		}
		
		
		/**
		 * 수신부 처리 TGT FileToFile 수정등록
		 */
		String tgtAdptrCd, tgtAdptrCdSeq;
		
		//** 인터페이스id로 어댑터정보 가져옴
		adptList = dao.selectListAdptrCheck(tgtWorkGrpCd,intfId,EIMSBatConstants.SNDRCVKIND_RCV, null);
		if( adptList.isEmpty() ) {
			logger.error("AdaptrRegister[FF]-U.TGT adptrCd is exist. intfId="+intfId+",tgtWorkGrpCd="+tgtWorkGrpCd);
			throw new Exception("AdaptrRegister[FF]-U.TGT adptrCd is exist. intfId="+intfId+",tgtWorkGrpCd="+tgtWorkGrpCd);
		}
		
		rltMap = adptList.get(0);		
		tgtAdptrCd = rltMap.get("ADPTRCD");
		tgtAdptrCdSeq = String.valueOf(rltMap.get("ADPTRCDSEQ"));

		try {
			//** 수신 상세 어댑터 등록 TSEAIEA05 
			FileAdapterVo tgtFileAdapterVo = new FileAdapterVo();
			tgtFileAdapterVo.setAdptrcd(tgtAdptrCd);
//			tgtFileAdapterVo.setAdptrcdseq(tgtAdptrCdSeq);
			tgtFileAdapterVo.setIntfid(intfId);
			tgtFileAdapterVo.setFtpname(mergeMap.get(EIMSBatConstants.INTFNAME));
			tgtFileAdapterVo.setFtparchivedir(mergeMap.get(EIMSBatConstants.TGTFILEPATH));
			tgtFileAdapterVo.setWorkGrpCd(tgtWorkGrpCd);
			//추가 기능 설정없음(체크파일:스케쥴시필요, 백업디렉토리)
			String eventYn = mergeMap.get(EIMSBatConstants.EVENTCALLVAL);
			if(EIMSBatConstants.EVENTCALLVAL_SCHED.equals(eventYn) ||
			   EIMSBatConstants.EVENTCALLVAL_EVENT.equals(eventYn)		) {
				tgtFileAdapterVo.setCheckname("chk");
				tgtFileAdapterVo.setFtpcheckdir(mergeMap.get(EIMSBatConstants.TGTFILEPATH));
				tgtFileAdapterVo.setNextoption("1");
			} 
			dao.updateSubFileAdaptr(tgtFileAdapterVo);
		}catch(Exception e) {
			logger.error(e);					
			throw new Exception("AdaptrRegister[FF]-U.TGT updateSubFileAdaptr Fail.");		
		}
		
	}
	
	//** 4-1. 인터페이스 아이디로 스케쥴 여부 체크	
	//기존에 있으면 그대로 사용.
	protected void makeScheRegister(String intfId, String userId, HashMap<String,String> mergeMap) throws Exception {
		
		/** mergeMapTimeValidation **/
		String startTime = mergeMap.get(EIMSBatConstants.POLLINGSTRTIME);
		String end__Time = mergeMap.get(EIMSBatConstants.POLLINGENDTIME);
		String cycleTime = mergeMap.get(EIMSBatConstants.POLLINGCYCLE);
		
		if(end__Time != null && StringUtils.isNotBlank(end__Time) && Integer.parseInt(end__Time.substring(0, 2)) >= 24) {
			throw new Exception("스케쥴의 EndTime은 23:59 이상 입력할 수 없습니다.");
		}
	   
		//** 있을 경우 수정, 없는 경우 신규로 생성
		//** 스케쥴 채번 규칙 ( U + _업무구분코드 + 처리유형(DD|FF) + D + DB타이머orFile(T|F) + Schedule Sequence
		String bjobMsgScheID = "";
		String thismsguseyn = "0";
		
		String batchType = mergeMap.get(EIMSBatConstants.BATCHTYPE);			
		
		String eventYn = mergeMap.get(EIMSBatConstants.EVENTCALLVAL);
		if(EIMSBatConstants.EVENTCALLVAL_SCHED.equals(eventYn)) {
			thismsguseyn = "1";
		}
		
		//** 스케쥴 생성 여부 체크(없으면 신규로 생성)
		bjobMsgScheID = dao.selectScheCheck(intfId);
		
		if( !EimsBatUtil.isStrEmpty(bjobMsgScheID) ) { // 스케쥴 수정
			
			try {
				//** 스케쥴 수정  TSEAIES07 
				BatScheduleVo batScheduleVo = new BatScheduleVo();
				batScheduleVo.setBjobmsgscheid(bjobMsgScheID);
				batScheduleVo.setIntfid(intfId);
				batScheduleVo.setThismsgschedesc(mergeMap.get(EIMSBatConstants.INTFNAME));
				batScheduleVo.setSndrcvstarthms(mergeMap.get(EIMSBatConstants.POLLINGSTRTIME));
				batScheduleVo.setSndrcvendhms(mergeMap.get(EIMSBatConstants.POLLINGENDTIME));
				batScheduleVo.setDaycycletime(mergeMap.get(EIMSBatConstants.POLLINGCYCLE));
				batScheduleVo.setThismsgamndrid(userId);	
				batScheduleVo.setThismsguseyn(thismsguseyn);
				
				dao.updateScheRegister(batScheduleVo);
			}catch(Exception e) {
				logger.error(e);					
				throw new Exception("ScheRegister[]-U updateScheRegister Fail.[bjobMsgScheID="+bjobMsgScheID+"]");		
			}
			
		}
		else { // 스케쥴 신규 생성
			//** 업무구분코드는 입력받은 어플리케이션 코드로 그룹코드를 발췌하여 온다.
			String workGrpCd = dao.selectWorkGrpcd(mergeMap.get(EIMSBatConstants.APPCD));//인터페이스 업무코드사용
			
			//** 스케쥴ID  채번 (U + _업무구분 + 배치유형 + _D + _F(파일_ + _T(테이블) + _001(일련번혼) 
			if(workGrpCd == null || workGrpCd.length() <= 0) {
				 throw new Exception("Invalid workGrpCd: [" + workGrpCd + "]");
			}
						
			String scheKind ="";
			if(EIMSBatConstants.BATCHTYPE_DB_DD.equals(batchType)) {				
				bjobMsgScheID = SCHE_ID_DD_D_T.replaceFirst("#", workGrpCd);
				scheKind = EIMSBatConstants.SCHEKIND_T;
			}
			else if(EIMSBatConstants.BATCHTYPE_FILE_FF.equals(batchType)) {				
				bjobMsgScheID = SCHE_ID_FF_D_F.replaceFirst("#", workGrpCd);
				scheKind = EIMSBatConstants.SCHEKIND_F;
			}
			
			// 다른 APPLCD로 등록되어있을 수도 있는 스케쥴 Mapping정보를 삭제합니다. (실제 스케쥴 ES07은 삭제하지 않음)
			dao.deleteScheRegister(intfId);
			// APPLCD 를 Key로 하는 스케쥴INDEX TABLE(EA07)에서 ScheduleIndex를 증가시키며 가져옵니다.
			int scheduleIndex = requiresNewTransaction_increaseAndGetScheduleIndex(workGrpCd);
			if(scheduleIndex >= 1000) {
				throw new Exception("Schedule Index가 1000을 초과하였습니다. 더 이상 Schedule을 생성할 수 없습니다.");
			}
			String scheduleIndexSuffix = String.format("%03d", scheduleIndex); // 1 -> 001, 50 -> 050
			bjobMsgScheID += scheduleIndexSuffix;
						
			try {
				//** 스케쥴 등록  TSEAIES07 
				BatScheduleVo batScheduleVo = new BatScheduleVo();
				batScheduleVo.setBjobmsgscheid(bjobMsgScheID);
				batScheduleVo.setIntfid(intfId);
				batScheduleVo.setBatchtype(batchType);
				batScheduleVo.setSchekind(scheKind);
				batScheduleVo.setThismsgschedesc(mergeMap.get(EIMSBatConstants.INTFNAME));
				batScheduleVo.setSndrcvstarthms(mergeMap.get(EIMSBatConstants.POLLINGSTRTIME));
				batScheduleVo.setSndrcvendhms(mergeMap.get(EIMSBatConstants.POLLINGENDTIME));
				batScheduleVo.setDaycycletime(mergeMap.get(EIMSBatConstants.POLLINGCYCLE));
				batScheduleVo.setThismsgregsntid(userId);	
				batScheduleVo.setThismsgamndrid(userId);	
				batScheduleVo.setThismsguseyn(thismsguseyn);
				
				dao.insertScheRegister(batScheduleVo);
			}catch(Exception e) {
				logger.error(e);					
				throw new Exception("ScheRegister[]-I insertScheRegister Fail.");		
			}
			
			
			try {
				//** 스케쥴 인터페이스 등록  TSEAIEA09 
				BatScheduleSubVo batScheduleSubVo = new BatScheduleSubVo();
				batScheduleSubVo.setBjobmsgscheid(bjobMsgScheID);
				batScheduleSubVo.setIntfid(intfId);
				batScheduleSubVo.setRegid(userId);
				
				dao.insertScheSubInterface(batScheduleSubVo);
			}catch(Exception e) {
				logger.error(e);					
				throw new Exception("ScheRegister[]-I insertScheSubInterface Fail.");		
			}
			
		}
		
	}
		
	/**
	 * Transaction 단위를 축소해 Index 겹침 오류를 회피하도록 함
	 */
	private int requiresNewTransaction_increaseAndGetScheduleIndex(String applCd) {
		return dao.increaseAndGetScheduleIndex(applCd);
	}

	public HashMap<String, String> merge(HashMap<String, String> intMap, HashMap<String, String> dbMap, HashMap<String, String> fileMap) throws Exception {

		//** 헤더에서 배치타입을 가져와 DB인지 File 인지 비교후 DB면 파일맵 머지 후 DB매을 머지 한다.(반대일 경우는 DB맵 머지후 File맵을 머지 한다)
		String pBatchType = intMap.get(EIMSBatConstants.BATCHTYPE);
		
		if(pBatchType == null) {
			logger.error("Fail BAT interface to batchType Null : "+ intMap);
			return intMap;			
		}
		
		if("DB".equals(pBatchType)) {
			intMap.putAll(fileMap);
			intMap.putAll(dbMap);			
		}
		
		if("File".equals(pBatchType)) {
			intMap.putAll(dbMap);
			intMap.putAll(fileMap);			
		}
		
		intMap = changeXmlSystemType(intMap);
		
		return intMap;
	}

	//** EIMS 수신데이터 로그 저장 TSEAIBJ09
	public String insertEimsLogRegister(HashMap<String, String> mergeMap) throws Exception{
		String mapString ="";
		
		HashMap<String,Object> paramMap = new HashMap<String,Object>();
		Iterator<String> mapInter = mergeMap.keySet().iterator();
		while(mapInter.hasNext()) {
			String key = mapInter.next();
			String value = mergeMap.get(key);
			mapString += "[" + key + "=" + value + "] ";
			if("appCd".equals(key)) {
				paramMap.put("syscd",value);
			}
			if("appCd".equals(key)) {
				paramMap.put("appcd",value);
			}
			if("infId".equals(key)) {
				paramMap.put("intfid",value);
			}
			if("batchType".equals(key)) {
				paramMap.put("batchtype",value);
			}
			if("authorId".equals(key)) {
				paramMap.put("reguserid",value);
			}			
		}
		paramMap.put("rcptncn",mapString);
		
		String rltStr = dao.insertEimsRcvRegister(paramMap);
		
		if(rltStr == null) {
			return "1";
		}
		return "0";
	}
	
	/**
	 * 시스템 접속정보 가지고 오기 (fileToFile sftp_key 인증서 방식(ID,DNS,PORT) , DBoDB jndi name)
	 * @param envrdvsncd
	 * @param sysdvsncd
	 * @param workGrpCd
	 * @param batchType
	 * @return
	 * @throws Exception
	 */
	private HashMap<String, String> getSysInfo(String envrdvsncd,String sysdvsncd,String workGrpCd,String batchType) throws Exception{
		
		HashMap<String, String> sysMap = dao.selectSystemInfo(envrdvsncd,sysdvsncd,workGrpCd,batchType);
		
		if(EIMSBatConstants.BATCHTYPE_DB_DD.equals(batchType) && 
				( (sysMap == null || sysMap.isEmpty()) ||  
				EimsBatUtil.isStrEmpty(sysMap.get(EIMSBatConstants.DBJNDI)) ) ){
			sysMap = null;
			
			logger.error("AdaptrRegister[DBToDB] selectSystemInfo Fail.");
			throw new Exception("[Fail] 시스템 정보 등록이 필요합니다.\n 인터페이스 담당자에게 문의하세요.\nSystemInfo(DB) not exist. sysCd="+sysdvsncd+", envrdvsncd="+envrdvsncd+", batchType="+batchType);
		}
		else if(EIMSBatConstants.BATCHTYPE_FILE_FF.equals(batchType) && 
				((sysMap == null || sysMap.isEmpty()) ||
						EimsBatUtil.isStrEmpty(sysMap.get(EIMSBatConstants.CNTNDNS2)) ||
				  EimsBatUtil.isStrEmpty(sysMap.get(EIMSBatConstants.CNTNID2)) ||
				  EimsBatUtil.isStrEmpty(sysMap.get(EIMSBatConstants.APPORT2)) )
				 ){			
			sysMap = null;
			
			logger.error("AdaptrRegister[FileToFile] selectSystemInfo Fail.");		
			throw new Exception("[Fail] 시스템 정보 등록이 필요합니다.\n인터페이스 담당자에게 문의하세요.\nSystemInfo(AP) not exist. sysCd="+sysdvsncd+", envrdvsncd="+envrdvsncd+", batchType="+batchType);
		}
		
		logger.debug("getSysInfo Map="+sysMap);
		
		return sysMap;
	}
		
	private HashMap<String, String> changeXmlSystemType(HashMap<String, String> mergeMap) throws Exception {
		//BATCHTYPE 엔진타입으로 젼환
		if( mergeMap.get(EIMSBatConstants.BATCHTYPE).equals("DB") ) {
			mergeMap.put(EIMSBatConstants.BATCHTYPE, "DD");
		}
		else if(mergeMap.get(EIMSBatConstants.BATCHTYPE).equals("File")  ) {
			mergeMap.put(EIMSBatConstants.BATCHTYPE, "FF");
		}
		
		//EVENTCALLVAL 엔진타입으로 젼환
		if(mergeMap.get(EIMSBatConstants.EVENTCALLVAL).equals("E")){
			mergeMap.put(EIMSBatConstants.EVENTCALLVAL, "1");
		}
		else{
			mergeMap.put(EIMSBatConstants.EVENTCALLVAL, "0");
		}
		
		//스케쥴 시간 포맷 변환
		String time = mergeMap.get(EIMSBatConstants.POLLINGSTRTIME);
		if(!EimsBatUtil.isStrEmpty(time)) {
			mergeMap.put(EIMSBatConstants.POLLINGSTRTIME, time.replace(":", ""));			
		}
		time = mergeMap.get(EIMSBatConstants.POLLINGENDTIME);
		if(!EimsBatUtil.isStrEmpty(time)) {
			mergeMap.put(EIMSBatConstants.POLLINGENDTIME, time.replace(":", ""));			
		}
		time = mergeMap.get(EIMSBatConstants.POLLINGCYCLE);
		if(!EimsBatUtil.isStrEmpty(time)) {
			mergeMap.put(EIMSBatConstants.POLLINGCYCLE, time.replace(":", ""));			
		}
		
		//TRNSRSLTRFLCTYN db adapter delYN 설정 전환
		if( TRNSRSLTRFLCTYN_Y.equals(mergeMap.get(EIMSBatConstants.TRNSRSLTRFLCTYN))
				) {
			mergeMap.put(EIMSBatConstants.TRNSRSLTRFLCTYN, "1");
		}
		else {
			mergeMap.put(EIMSBatConstants.TRNSRSLTRFLCTYN, "0");
		}		
		String query = mergeMap.get(EIMSBatConstants.SRCDBRSLTRFLCTQUERY);
		if( EimsBatUtil.isStrEmpty(query) ) {
			mergeMap.put(EIMSBatConstants.SRCDBRSLTRFLCTQUERY, "");			
		}
		
		
		return mergeMap;
	}
	
	private boolean isUserAppCdCheck(String userId, String appCd) throws Exception{
		
		int rlt = dao.selectUserAppCdCheck(userId, appCd);
		logger.debug("isUserAppCdCheck : "+rlt);
		
		if(rlt > 0) {
			return true;			
		} else {			
			return false;
		}
		
	}	
}