package com.eactive.eai.rms.ext.eims;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.View;

import com.eactive.eai.agent.command.CommonCommand;
import com.eactive.eai.common.util.NullControl;
import com.eactive.eai.common.util.SystemUtil;
import com.eactive.eai.rms.common.base.OnlBaseAnnotationController;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.interceptor.InterceptorSkipController;
import com.eactive.eai.rms.common.logging.UserAccessLogger;
import com.eactive.eai.rms.common.mmilog.MMILogDao;
import com.eactive.eai.rms.common.util.StringUtils;
import com.eactive.eai.rms.onl.common.util.DateUtil;
import com.eactive.eai.transformer.layout.LayoutManager;
import com.eactive.eai.transformer.layout.LayoutTypeManager;

@Controller
public class EIMSSyncController extends OnlBaseAnnotationController implements InterceptorSkipController {

    private static final Logger logger = Logger.getLogger(EIMSSyncController.class);

    @Autowired
    @Qualifier("eimsSyncService")
    private EIMSSyncService service;
    
    @Autowired
    @Qualifier("monitoringContext")
    private MonitoringContext monitoringContext;
    
    @Autowired
    @Qualifier("mmiLogDao")
    private MMILogDao mmiLogDao;
    
    @Autowired
    private LayoutManager layoutManager;
    
    @Autowired
    private LayoutTypeManager layoutTypeManager;

	

    /**
     * 통합인터페이스 시스템(EIMS)에서 전문 레이아웃에 대한 INSERT, DELETE 요청
     * 
     * 배포 파라미터 key
     * 인터페이스 : INTERFACE
     * 레이아웃   : LAYOUT_SOURCE_REQ, LAYOUT_SOURCE_RES, LAYOUT_TARGET_REQ, LAYOUT_TARGET_REQ
     * 변환        :TRANSFORM_REQ, TRANSFORM_RES
     * @param request
     * @param response
     * @param schema
     * @return
     * @throws Exception
     */
    @RequestMapping(value= "/eimsSync.file", method=RequestMethod.POST)
    public View parseMessage(HttpServletRequest request, HttpServletResponse response) throws Exception {
    	
        UserAccessLogger.log(request, "Message", "L", "cmd=Message");
		HashMap<String,String> map = new HashMap<String,String>();
		StringBuilder sb = new StringBuilder();
		StringBuilder frame = new StringBuilder();
		
		logger.debug("parseMessage content-Type="+request.getContentType());
		
		String deployIfId       = "";
		String ver           = "";
		String eaiSvcName    = "";
		String eaiSevrDstcd  = "";
		String cnvsnNames    = "";
		String loutNames     = "";
		String userId        = "";
		
		HashMap<String,Object> logMap = new HashMap<String,Object>();
		StringBuffer buffer = new StringBuffer();
        try{
        	if (!SystemUtil.isDevServer()){
        		throw new Exception("It works only on the development server.");
        	}
			for (String key : request.getParameterMap().keySet()){
				String [] datas= request.getParameterValues(key);
				StringBuffer resultS = new StringBuffer();
				for(String data : datas){
					resultS.append(data);
				}
				if (key.startsWith("INTERFACE") || key.startsWith("LAYOUT_") || key.startsWith("TRANSFORM_") ){
					buffer.append(resultS.toString()).append("\n");
				}
//				if (key.startsWith("FM") ){
//					cnvsnNames += ","+key;
//				}
//				if (key.startsWith("FD")){
//					loutNames += ","+key;
//				}
				
				logger.info("receive Data "+key+"="+resultS.toString());
				map.put(key, resultS.toString());
			}
		
			HashMap<String,Object> inter = null;
			HashMap<String,Object> info = null;
			
			
			for(String key : map.keySet()){
				if (key.startsWith("INTERFACE") ){
					info = EIMSParser.parseInfo(map.get(key));
				}
			}
	        if (info == null){
	        	throw new Exception("Interface information does not exist.");
	        }
			       eaiSvcName    = (String)info.get(EIMSParserKey.SYS_SVC_NAME);//EAI서비스코드
			String eaiBzwkDstcd  = (String)info.get(EIMSParserKey.APP_CD);  //EAI업무구분코드
			       eaiSevrDstcd  = (String)info.get(EIMSParserKey.INF_DST_CD); //M/E/F
			String interfaceType = (String)info.get(EIMSParserKey.INTF_TYPE); //인터페이스유형
			       deployIfId    = (String)info.get(EIMSParserKey.INF_ID); //
			       ver           = (String)info.get(EIMSParserKey.VER); // 버전번호
			
			String srcSysId      = (String)info.get(EIMSParserKey.SRC_ADT_ID); //소스 시스템ID
			String tgtSysId      = (String)info.get(EIMSParserKey.TRG_ADT_ID); //타겟 시스템ID
			String resSrcSysId   = (String)info.get(EIMSParserKey.RES_SRC_ADT_ID); //응답 소스 시스템ID
			
			String srcSysType    = (String)info.get(EIMSParserKey.SRC_COM_TYPE); //소스 시스템 type
			String tgtSysType    = (String)info.get(EIMSParserKey.TRG_COM_TYPE); //타겟 시스템 type
			
			       userId        = (String)info.get(EIMSParserKey.AUTHOR); //사용자ID
			String outBizCd      = (String)info.get(EIMSParserKey.EXT_BIZ_CD); //대외업무구분코드
//			String stdErrMpng    = (String)info.get(EIMSParserKey.STD_ERR_MPNG); //표준 에러코드 사용여부
			
			/** XML 파싱 전에 layoutNames transformNames 추출 **/
			List<String> layoutNameList = new ArrayList<>();
			List<String> cnvsnNameList = new ArrayList<>();
			for (Entry<String, String> entry : map.entrySet()) {
				if (entry.getKey().startsWith("LAYOUT")) {
					String layoutName = EIMSParser.getResourceName(entry.getValue(), "LAYOUT");
					if (StringUtils.isNotBlank(layoutName)) {
						layoutNameList.add(layoutName);
					}
				} else if (entry.getKey().startsWith("TRANSFORM")) {
					String cnvsnName = EIMSParser.getResourceName(entry.getValue(), "TRANSFORM");
					if (StringUtils.isNotBlank(cnvsnName)) {
						cnvsnNameList.add(cnvsnName);
					}
				}
			}
			if (layoutNameList.size() > 0) {
				loutNames = String.join(",", layoutNameList.toArray(new String[0]));
			}
			if (cnvsnNameList.size() > 0) {
				cnvsnNames = String.join(",", cnvsnNameList.toArray(new String[0]));
			}
			
			///////////////////////////////////////////////
			//서버구분코드로 DataSourceType 변경
			// M : 내부MCI(MCI) , E : EAI(EAI), F : 외부MCI(FEP)
			// 개발은 1,2,3 은 DSG 로  4는 ZSG로 처리 한다.
			///////////////////////////////////////////////
			String serverType = monitoringContext.getStringProperty(MonitoringContext.EIMS_SYNC_SERVERTYPE, "M=MCI,U=MCU,E=EAI,F=FEP");
			HashMap<String,String> serverDstcdMap = new HashMap<String,String>();
			Matcher matcher = Pattern.compile("[ ]*([A-Z]+)[ ]*=[ ]*([A-Z]+)[ ]*").matcher(serverType);
			while(matcher.find()) {
			    String key = matcher.group(1).trim();
			    String value = matcher.group(2).trim();
			    serverDstcdMap.put(key, value);
			} 
			if (serverDstcdMap.containsKey(eaiSevrDstcd)){
				String dataSourceType = serverDstcdMap.get(eaiSevrDstcd);
				DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(dataSourceType));
			}else{
				throw new Exception("Unsupported interface classification code."+eaiSevrDstcd);
			}

			//interface 업무구분코드 valication
			boolean isApp = service.selecAppIsYn(new HashMap(){{put("eaiBzwkDstcd",eaiBzwkDstcd);}});
			if (!isApp){
				throw new Exception("This APP CD is not supported by the interface." + eaiBzwkDstcd);
			}
//			//변환 업무구분코드 validation
//			String[] cnvsnNameList = cnvsnNames.split(",");
//			for(String cnvsnName : cnvsnNameList){
//				if (!StringUtils.isBlank(cnvsnName) && cnvsnName.length() > 5 ){
//					String appcode = cnvsnName.substring(2,5);
//					isApp = service.selecAppIsYn(new HashMap(){{put("eaiBzwkDstcd",appcode);}});
//					if (!isApp){
//						throw new Exception("변환 에서 지원 하지 않는 APP CD 입니다. " + appcode);
//					}
//					
//				}
//			}
//			//layout 업무구분코드 validation
//			String[] layoutNameList = loutNames.split(",");
//			for(String layoutName : layoutNameList){
//				if (!StringUtils.isBlank(layoutName) && layoutName.length() > 5 ){
//					String appcode = layoutName.substring(2,5);
//					isApp = service.selecAppIsYn(new HashMap(){{put("eaiBzwkDstcd",appcode);}});
//					if (!isApp){
//						throw new Exception("레이아웃 에서 지원 하지 않는 APP CD 입니다. " + appcode);
//					}
//				}
//			}
			
			//adapter validation
			if ("A".equals(srcSysType) && "S".equals(tgtSysType) && "S".equals(interfaceType)){
				if (StringUtils.isEmpty(srcSysId)){
					throw new Exception("No source adapter selected.");
				}	
				if (StringUtils.isEmpty(tgtSysId)){
					throw new Exception("No target adapter selected.");
				}
				if (StringUtils.isEmpty(resSrcSysId)){
					throw new Exception("No source response adapter selected.");
				}
			}else if ("A".equals(srcSysType) && "S".equals(tgtSysType) && "R".equals(interfaceType)){
				if (StringUtils.isEmpty(srcSysId)){
					throw new Exception("No source adapter selected.");
				}		
			}else{
				if (StringUtils.isEmpty(srcSysId)){
					throw new Exception("No source adapter selected.");
				}	
				if (StringUtils.isEmpty(tgtSysId)){
					throw new Exception("No target adapter selected.");
				}
			}
			
			// adapter 파서 
			Map<String, Map<String, String>> adapters = service.selectAdapterForNickName(srcSysId,tgtSysId,resSrcSysId);
			String adptrMsgDstcd = adapters.get(EIMSParserKey.SRC).get("ADPTRMSGDSTCD");
			
			//option 정보
			//1.큐 프라퍼트
			//2.B2B 프로퍼티
			//3.FailOver 프라퍼티
			HashMap options = service.getEngineOption(serverDstcdMap.get(eaiSevrDstcd),eaiSvcName, outBizCd );
			
			// interface 파서 
			for(String key : map.keySet()){
				if (key.startsWith("INTERFACE")){
					inter = EIMSParser.parseInterface(map.get(key),adapters, options);
					logger.info("interface parsing " +inter);
				}
			}
			HashMap<String,String> reverseName = new HashMap<String,String>();
			HashMap<String,String> normalName = new HashMap<String,String>();
			
			// layout 파서 
			List<HashMap<String,Object>> layouts = new ArrayList<HashMap<String,Object>>();
			for(String key : map.keySet()){
				if (key.startsWith("LAYOUT")){
//					if (key.startsWith("FDEAI_") && key.endsWith("_ERR")){
//						continue;
//					}
					EIMSParser.layoutDupValidation(map.get(key));
					HashMap<String,Object> layout = EIMSParser.parseLayout(map.get(key),eaiSevrDstcd);
					layouts.add( layout);
					String layoutName = (String)layout.get("loutName");
					logger.info("layout parsing " + layout);
					reverseName.put(layoutName, key );
					normalName.put(key, layoutName );
				}
			}
			//변환 파서
			List<HashMap<String,Object>> transforms = new ArrayList<HashMap<String,Object>>();
			//HashMap<String,String> replaceTransform = new HashMap<String,String>();
			for(String key : map.keySet()){
				if (key.startsWith("TRANSFORM")){
					HashMap<String,Object> transform = EIMSParser.parseTransform(map.get(key), eaiBzwkDstcd, eaiSevrDstcd,userId);
					transforms.add( transform );
					String cnvsnName = (String)transform.get("cnvsnName");
					logger.info("transform parsing " + transform);
					reverseName.put(cnvsnName, key );
					normalName.put(key, cnvsnName );
				}
			}
		
			
			EIMSParser.validation(srcSysType, tgtSysType, interfaceType,adapters, transforms, layouts, eaiSevrDstcd);
			
			
			// 변환 을 EAI서비스 코드에 셋팅하는 로직
			
			List<HashMap<String,Object>> he02s =  (List<HashMap<String,Object>>)inter.get("he02");
			if (he02s != null){
				HashMap<String,Object> he02 = (HashMap<String, Object>) he02s.get(0);
				if (he02 != null){
					//async-async 요청인데 RES로 되어 있는거 보강로직
					if ("A".equals(srcSysType) && "A".equals(tgtSysType) && transforms.size()==1) {
						String cnvsnName =(String)transforms.get(0).get("cnvsnName");
						he02.put("chngEonot"                , "1"        ); // 변환유무             
						he02.put("chngMsgIDName"            , cnvsnName  ); // 변환메시지ID명         
					}else{
						for(HashMap<String,Object> tr : transforms) {
							String cnvsnName = (String)tr.get("cnvsnName");
							if (cnvsnName.endsWith("_REQ")){
								he02.put("chngEonot"                , "1"        ); // 변환유무             
								he02.put("chngMsgIDName"            , cnvsnName  ); // 변환메시지ID명         
							}else if (cnvsnName.endsWith("_RES")){
								if ("A".equals(srcSysType) && "A".equals(tgtSysType) && "R".equals(interfaceType)  ){//Async Async 패턴 응답이 경우
									he02.put("chngEonot"                , "1"        ); // 변환유무             
									he02.put("chngMsgIDName"            , cnvsnName  ); // 변환메시지ID명     								
								} else {
									he02.put("bascRspnsChngEonot"       , "1"        ); // 기본응답변환유무             
									he02.put("bascRspnsChngMsgIDName"   , cnvsnName  ); // 기본응답변환메시지ID명         
								}
							}else if (cnvsnName.endsWith("_ERR")){
								he02.put("errRspnsChngEonot"        , "1"        ); // 오류응답변환유무   
								he02.put("errRspnsChngMsgIDName"    , cnvsnName  ); // 오류응답변환메시지ID명
							}
						}
					}
//					//표준에러매핑 관련
//					if ("Y".equals(stdErrMpng)){
//						
//						//에러변환이 있는경우 표준에러 매핑을 셋팅할수 없음.
//						if ("1".equals(he02.get("errRspnsChngEonot"))){
//							throw new Exception("에러 변환을 셋팅한 상태에서는 표준 오류 매핑 사용을 Y 로 셋팅 할수 없습니다.");
//						}
//						if ("A".equals(srcSysType) && "S".equals(tgtSysType) && "R".equals(interfaceType)){
//							throw new Exception("표준에러매핑을 셋팅할수 없는 패턴입니다. 거래패턴 :"+srcSysType +"-" +tgtSysType +" 송수신타입 : "+interfaceType );
//						}
//						String srcKesaUseYn = adapters.get(EIMSParserKey.SRC).get("KESAUSEYN");
//						String tgtKesaUseYn = adapters.get(EIMSParserKey.TGT).get("KESAUSEYN");
//						String srcMsgDstcd = adapters.get(EIMSParserKey.SRC).get("ADPTRMSGDSTCD");
//						String tgtMsgDstcd = adapters.get(EIMSParserKey.TGT).get("ADPTRMSGDSTCD");
//						if (!"0".equals(srcKesaUseYn) && !"0".equals(tgtKesaUseYn)){
//							//Async - Async 응답에서만 셋팅
//							//Sync  - Async 요청에서만셋팅
//							//Sync  - Sync  요청만 있음 
//							//Async - Sync  요청만 있음
//							String cnvsnName = "";
//							if ("A".equals(srcSysType) && "A".equals(tgtSysType) && "R".equals(interfaceType)){
//								cnvsnName = "TRANSFORM_EAI_" + srcMsgDstcd +"TO" + tgtMsgDstcd + "_ERR";
//								he02.put("errRspnsChngEonot"        , "1"        ); // 오류응답변환유무   
//								he02.put("errRspnsChngMsgIDName"    , cnvsnName  ); // 오류응답변환메시지ID명
//							}else if ("S".equals(srcSysType) && "A".equals(tgtSysType) && "S".equals(interfaceType)){
//								cnvsnName = "TRANSFORM_EAI_" + tgtMsgDstcd +"TO" + srcMsgDstcd + "_ERR";
//								he02.put("errRspnsChngEonot"        , "1"        ); // 오류응답변환유무   
//								he02.put("errRspnsChngMsgIDName"    , cnvsnName  ); // 오류응답변환메시지ID명
//							}else if ( "S".equals(tgtSysType) ){
//								cnvsnName = "TRANSFORM_EAI_" + tgtMsgDstcd +"TO" + srcMsgDstcd + "_ERR";
//								he02.put("errRspnsChngEonot"        , "1"        ); // 오류응답변환유무   
//								he02.put("errRspnsChngMsgIDName"    , cnvsnName  ); // 오류응답변환메시지ID명
//							}else{
//								throw new Exception("표준에러매핑을 셋팅할수 없는 패턴입니다. 거래패턴 :"+srcSysType +"-" +tgtSysType +" 송수신타입 : "+interfaceType );
//							}
//						}else{
//							throw new Exception("소스("+srcKesaUseYn+")와 타겟("+tgtKesaUseYn+")이 두개다 kesa가 아닐경우 표준 오류 매핑 사용을 Y 로 셋팅 할수 없습니다.");
//						}
//					
//					}
				}
				logger.info("he02 setting " + he02);
			}
			///////////////////////
			// TR , AK
			//////////////////////
			List<HashMap<String,Object>> tracekeys = new ArrayList<HashMap<String,Object>>();
			
			// tr , ak  파서 
			List<String> parseKeys = new ArrayList<String>();
			for(String key : map.keySet()){
				if (key.startsWith("INTERFACE")){
					parseKeys = EIMSParser.parseKey(map.get(key));
					logger.info("tr ,ak  parsing " +parseKeys);
				}
			}
			//tr ,ak validation
			for(String parseKey : parseKeys){
				String[] keys = parseKey.split(",");
				String keyType = keys[0];
				String keyIndex = keys[1];
				String layoutFullPath = keys[2];
				String layout = layoutFullPath.split("\\.")[0];
//				if (map.containsKey(layout)){
				if (reverseName.containsKey(layout)){
					String data = map.get(reverseName.get(layout));
					if (EIMSParser.parseKeyValidation(data,layoutFullPath)){
						tracekeys.add(EIMSParser.parseKey2(eaiSvcName, keyType, keyIndex, adptrMsgDstcd,layoutFullPath, eaiSevrDstcd));
					}else{
						throw new Exception("The key path for the field extraction information[필드추출정보] or log lookup key[로그조회키] does not exist."+layoutFullPath);
					}
				}else{
					throw new Exception("Field extraction information or log search key key path(" + layoutFullPath + ") does not exist in the layout used. List of all deployed layouts: " + loutNames);
				}
			}
			//참조메시지에 대한 정의-20200527 jun's
			//1.변환매핑이 없고 로그키(필드추출정보)가 없을 경우 참조메시지ID를 셋팅한다.
			//2.저장시에도 아래의 조건 만족하는경우에만 DB에서 DELETE & INSERT 한다.
			//  => 조건이 안맞을시에는 ms02가 생성이 안되고 ASIS 마이그레이션 데이터가 있더라도 삭제 하지 않는다.
			if (transforms.size() == 0 && tracekeys.size() == 0 ){
				String refMessage ="";
				
				if ("A".equals(srcSysType) && "A".equals(tgtSysType) ){
					if ("S".equals(interfaceType)){
						refMessage = normalName.get("LAYOUT_SOURCE_REQ");
					}else{
						refMessage = normalName.get("LAYOUT_TARGET_REQ");
					}
				}

//				for(String key : map.keySet()){
//					if (key.startsWith("LAYOUT")){
//						refMessage = key;
//						break;
//					}
//				}

				List<HashMap<String,Object>> ms02s =  new ArrayList<HashMap<String,Object>>();
				if (!StringUtils.isBlank(refMessage)){
					// interface 에 ms02 설정
					HashMap<String,Object> ms02 =  new HashMap<String,Object>();
					ms02.put("EAISVCNAME", eaiSvcName);
					ms02.put("SVCPRCSSNO", "1");
					ms02.put("REFMSGIDNO", "1");
					ms02.put("REFMSGIDNAME", refMessage);
					ms02s.add(ms02);
				}
				inter.put("ms02", ms02s);	
				
			}

			// merge 로직 시작
			service.transactionEIMSSync(inter, layouts, transforms, tracekeys, userId);

			/** LayoutManager Reload Start **/
			for(HashMap<String, Object> layout : layouts) {
				
				String layoutName = (String)layout.get("loutName");
				
				try {
					layoutTypeManager.reload();
					layoutManager.reload(layoutName, DataSourceContextHolder.getDataSourceType().getJndiName(),
							DataSourceContextHolder.getDataSourceType().getSchema(), null);
				} catch (Exception e) {
					
					throw new Exception("Layout validation error : please check " + layoutName);
				}
				
			}
			/** LayoutManager Reload End **/ 
			
			CommonCommand command = null;
			
			//layout동기화
			for(HashMap<String,Object> layout : layouts){
				String loutName = (String) layout.get("loutName");
				command = new CommonCommand("com.eactive.eai.agent.transformer.ReloadLayoutCommand",loutName);
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("Layout sync error: "+loutName);
				}
			}
			
			//변환등기화
			for(HashMap<String,Object> transform : transforms){
				String cnvsnName = (String)transform.get("cnvsnName");
				command = new CommonCommand("com.eactive.eai.agent.transformer.ReloadTransformCommand",cnvsnName);
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("Transform sync error: "+cnvsnName);
				}
			}
			
			//인터페이스 동기화
			if (!StringUtils.isEmpty(eaiSvcName)){
	    		command = new CommonCommand("com.eactive.eai.agent.eaimessage.ReloadEAIMessageCommand",eaiSvcName);
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("Interface sync error: "+eaiSvcName);
				}
	    	}
			
			//추출키 동기화
			if (!StringUtils.isEmpty(eaiSvcName)){
				command = new CommonCommand("com.eactive.eai.agent.bizkey.ReloadBizKeyCommand",eaiSvcName+",TR");
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("field extraction key sync error: "+eaiSvcName);
				} 
				command = new CommonCommand("com.eactive.eai.agent.bizkey.ReloadBizKeyCommand",eaiSvcName+",AK");
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("log search key sync error: "+eaiSvcName);
				} 
			}
			//내부표준전문 동기화
			if (!StringUtils.isEmpty(eaiSvcName)){
				ArrayList<HashMap<String, Object>> hs04s = (ArrayList<HashMap<String, Object>>)inter.get("hs04");
		        if (hs04s != null){
		        	for(HashMap<String,Object> hs04 : hs04s){
		        		String bzwkSvcKeyName = (String)hs04.get("bzwkSvcKeyName");
		        		command = new CommonCommand("com.ext.eai.agent.stdmessage.ReloadSTDMessageCommand",bzwkSvcKeyName);
		        		if (!validate(agentUtilService.broadcast(command))){
		        			throw new Exception("Internal standard message sync error: "+bzwkSvcKeyName);
		        		} 
		        	}
		        }
			}
			//juns 어댑터 메시지키 동기화 삭제
//			//어댑터 메시지키 동기화
//			if (!isMessageKeySame){
//		        List<HashMap<String,Object>> fr04s = (List<HashMap<String,Object>>)inter.get("fr04");
//		        if (fr04s != null && fr04s.size()>0){
//	        		String adptrBzwkGroupName = (String)fr04s.get(0).get("adptrBzwkGroupName");
//	        		String key = adptrBzwkGroupName +",I";
//	        		command = new CommonCommand("com.eactive.eai.agent.messagekey.ReloadMessageKeyCommand",key);
//	        		if (!validate(agentUtilService.broadcast(command))){
//	        			throw new Exception("어댑터 메시지키 동기화 오류 "+adptrBzwkGroupName);
//	        		} 
//		        }
//			}
			
			sb.append(resultInterface(deployIfId, ver, "True", "Successfully processed."));
        } catch(Exception e){
        	logger.error("EIMSSyncController error="+e.getMessage(),e);
        	sb.append(resultInterface(deployIfId, ver, "False",e.getMessage()));
        } 

        frame.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        frame.append(sb.toString());
        
        
        
        
        
        //EIMS Log data  
        DataSourceType dt = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING);
        String schemaId = "";
		
		if(dt != null){
			DataSourceContextHolder.setDataSourceType(dt);
			schemaId =dt.getSchema();
		}else{
			logger.error("DataSourceType is null");
			return null;
		}
		//HashMap paramMap = new HashMap();
		 
		logMap.put("schemaId"     , schemaId);
		logMap.put("msgDpstHMS"   , DateUtil.getDateTimeMilliSecound());
		logMap.put("eaiSvcName"   , NullControl.addSpace(eaiSvcName));
		logMap.put("eaiSevrDstcd" , NullControl.addSpace(eaiSevrDstcd));
		logMap.put("cnvsnName"    , NullControl.addSpace(cnvsnNames));
		logMap.put("loutName"     , NullControl.addSpace(loutNames));
		logMap.put("reqDstcd"     , NullControl.addSpace(buffer.toString()));
		logMap.put("resDstcd"     , NullControl.addSpace(frame.toString()));
		logMap.put("interfaceId"  , NullControl.addSpace(deployIfId));
		logMap.put("deployId"     , NullControl.addSpace(userId));
		
		try{
			mmiLogDao.insert(logMap);
		}catch(Exception e){
			logger.error("db insert error : " + logMap.toString(),e);
		}
        response.setCharacterEncoding("UTF-8");
        
		ServletOutputStream sos = null;
    	try {
    		sos = response.getOutputStream();
    		sos.write(frame.toString().getBytes("UTF-8"));
    	} catch( Exception e ) {
    		//취약점소스 수정 2020.08.24
    		logger.error(" error", e); 
    	} finally {
    		if( sos != null ) sos.close();
    	}
    	return null;
    }
    @RequestMapping(value= "/eimsSync.file",params = "cmd=DELETE", method=RequestMethod.POST)
    public View messageDelete(HttpServletRequest request, HttpServletResponse response) throws Exception {
   	
        UserAccessLogger.log(request, "Message", "L", "cmd=delete");
		HashMap<String,String> map = new HashMap<String,String>();
		StringBuilder sb = new StringBuilder();
		StringBuilder frame = new StringBuilder();
		
		logger.debug("parseMessage content-Type="+request.getContentType());
		
		HashMap<String,Object> logMap = new HashMap<String,Object>();
		StringBuffer buffer = new StringBuffer();    
		
		/*
		 * 삭제 하기 위해 필요한 항목
		 * 1. eaiSevrDstcd
		 * 1. eaiSvcName
		 * 2. bzwkSvcKeyNames
		 * 3. transforms
		 * 4. layouts
		 * 5. deployIfId          배포 인터페이스 ID
		 */
		String eaiSevrDstcd   = null;
		String eaiSvcName     = null;
		String deployIfId     = null;
		String ver            = null;
		String userId         = null;
		String cnvsnNames     = "";
		String loutNames      = "";
		
		List<String> bzwkSvcKeyNames = new ArrayList<String>();
		List<String> layouts = new ArrayList<String>();
		List<String> transforms = new ArrayList<String>();
		
    	try{
        	if (!SystemUtil.isDevServer()){
        		throw new Exception("It works only on the development server.");
        	}
			for (String key : request.getParameterMap().keySet()){
				String [] datas= request.getParameterValues(key);
				StringBuffer resultS = new StringBuffer();
				for(String data : datas){
					resultS.append(data);
				}
				if (key.startsWith("INTERFACE") || key.startsWith("LAYOUT_") || key.startsWith("TRANSFORM_") ){
					buffer.append(resultS.toString()).append("\n");
				}
			
				logger.info("receive Data "+key+"="+resultS.toString());
				map.put(key, resultS.toString());
			}
			
			
			for(String key : map.keySet()){
				if (key.startsWith("INTERFACE") ){
					HashMap<String,Object> info = EIMSParser.parseInfo(map.get(key));
					if (info != null){
						eaiSevrDstcd = (String)info.get(EIMSParserKey.INF_DST_CD); //M/E/F
						String delYn = (String)info.get(EIMSParserKey.DEL_YN);
						deployIfId   = (String)info.get(EIMSParserKey.INF_ID); //
						ver          = (String)info.get(EIMSParserKey.VER); // 버전번호
						userId       = (String)info.get(EIMSParserKey.AUTHOR); //사용자ID
						if (delYn != null && "Y".equals(delYn)){
							String sysSvcName = (String)info.get(EIMSParserKey.SYS_SVC_NAME);
							if (!StringUtils.isBlank(sysSvcName)){
								eaiSvcName = sysSvcName;
							}
						}
					}
//					bzwkSvcKeyNames = EIMSParser.parseBzwkSvcKeyNames(map.get(key));
				}
			}
			
			for(String key : map.keySet()){
				if (key.startsWith("LAYOUT_")){
					String layout = EIMSParser.parseDeleteLayoutName(map.get(key));
					if (!StringUtils.isBlank(layout)){
						layouts.add(layout);
						loutNames  += ","+layout;
					}
				}
			}
			
			///////////////////////////////////////////////
			//서버구분코드로 DataSourceType 변경
			// M : 내부MCI(MCI) , E : EAI(EAI), F : 외부MCI(FEP)
			// 개발은 1,2,3 은 DSG 로  4는 ZSG로 처리 한다.
			///////////////////////////////////////////////
			String serverType = monitoringContext.getStringProperty(MonitoringContext.EIMS_SYNC_SERVERTYPE, "M=MCI,U=MCU,E=EAI,F=FEP");
			HashMap<String,String> serverDstcdMap = new HashMap<String,String>();
			Matcher matcher = Pattern.compile("[ ]*([A-Z]+)[ ]*=[ ]*([A-Z]+)[ ]*").matcher(serverType);
			while(matcher.find()) {
			    String key = matcher.group(1).trim();
			    String value = matcher.group(2).trim();
			    serverDstcdMap.put(key, value);
			} 
			if (serverDstcdMap.containsKey(eaiSevrDstcd)){
				String dataSourceType = serverDstcdMap.get(eaiSevrDstcd);
				DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(dataSourceType));
			}else{
				throw new Exception("Unsupported interface classification code."+eaiSevrDstcd);
			}
			//
			final String fEaiSvcName = eaiSvcName;
			transforms = service.selectTransformListForEaiSvcName(new HashMap(){{put("eaiSvcName",fEaiSvcName);}});
			if (transforms != null){
				for(String transform : transforms){
					cnvsnNames  += ","+transform;
				}
			}
			
			/** 업무서비스키 List 불러오기 **/
			List<String> bzwkKeyList = service.selectBzwkSvcKeyNameForEaiSvcName(new HashMap(){{put("eaiSvcName",fEaiSvcName);}});
			bzwkSvcKeyNames = bzwkKeyList != null? bzwkKeyList : new ArrayList<>();
			
			service.deleteAll(eaiSvcName, bzwkSvcKeyNames, transforms , layouts);
			
	    	CommonCommand command = null;
    		if (StringUtils.isNotBlank(eaiSvcName)){
				//인터페이스 삭제 동기화
				command = new CommonCommand("com.eactive.eai.agent.eaimessage.RemoveEAIMessageCommand",eaiSvcName);
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("Interface sync error: "+eaiSvcName);
				}
				//추출키 삭제 동기화
				command = new CommonCommand("com.eactive.eai.agent.bizkey.RemoveBizKeyCommand",eaiSvcName+",TR");
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("field extraction key sync error: "+eaiSvcName);
				} 
				command = new CommonCommand("com.eactive.eai.agent.bizkey.RemoveBizKeyCommand",eaiSvcName+",AK");
				if (!validate(agentUtilService.broadcast(command))){
					throw new Exception("log search key sync error: "+eaiSvcName);
				}
    			//내부표준전문 삭제 동기화
    			if(bzwkSvcKeyNames != null){
					for(String bzwkSvcKeyName : bzwkSvcKeyNames){
						command = new CommonCommand("com.ext.eai.agent.stdmessage.RemoveSTDMessageCommand",bzwkSvcKeyName);
						if (!validate(agentUtilService.broadcast(command))){
							throw new Exception("Internal standard message sync error: "+bzwkSvcKeyName);
						} 
					}
    			}
    			//변환 삭제 동기화
    			if(transforms != null){
    				for(String  cnvsnName : transforms){
    					command = new CommonCommand("com.eactive.eai.agent.transformer.RemoveTransformCommand",cnvsnName);
    					if (!validate(agentUtilService.broadcast(command))){
    						throw new Exception("Transform sync error: "+cnvsnName);
    					}
    				}
    			}
    		}
			//레이아웃 삭제 동기화
			if(layouts != null){
				for(String layout : layouts){
					command = new CommonCommand("com.eactive.eai.agent.transformer.RemoveLayoutCommand",layout);
					if (!validate(agentUtilService.broadcast(command))){
						throw new Exception("Layout sync error: "+layout);
					}
				}
			}
    		sb.append(resultInterface(deployIfId, ver, "True", "Successfully processed(deleted)."));
    	}catch(Exception e){
    		logger.error("EIMSSyncController error="+e.getMessage(),e);
    		sb.append(resultInterface(deployIfId, ver, "False",e.getMessage()));
    	}
    	
        frame.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        frame.append(sb.toString());
        
        //EIMS Log data  
        DataSourceType dt = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING);
        String schemaId = "";
		
		if(dt != null){
			DataSourceContextHolder.setDataSourceType(dt);
			schemaId =dt.getSchema();
		}else{
			logger.error("DataSourceType is null");
			return null;
		}
		//HashMap paramMap = new HashMap();
		
		logMap.put("schemaId"     , schemaId);
		logMap.put("msgDpstHMS"   , DateUtil.getDateTimeMilliSecound());
		logMap.put("eaiSvcName"   , NullControl.addSpace(eaiSvcName));
		logMap.put("eaiSevrDstcd" , NullControl.addSpace(eaiSevrDstcd));
		logMap.put("cnvsnName"    , NullControl.addSpace(cnvsnNames));
		logMap.put("loutName"     , NullControl.addSpace(loutNames));
		logMap.put("reqDstcd"     , NullControl.addSpace(buffer.toString()));
		logMap.put("resDstcd"     , NullControl.addSpace(frame.toString()));
		logMap.put("interfaceId"  , NullControl.addSpace(deployIfId));
		logMap.put("deployId"     , NullControl.addSpace(userId));
		
		try{
			mmiLogDao.insert(logMap);
		}catch(Exception e){
			logger.error("db insert error : " + logMap.toString(),e);
		}
        
        
        response.setCharacterEncoding("UTF-8");
        
		ServletOutputStream sos = null;
    	try {
    		sos = response.getOutputStream();
    		sos.write(frame.toString().getBytes("UTF-8"));
    	} catch( Exception e ) {
    		logger.error(e.getMessage(),e);
    	} finally {
    		if( sos != null ) sos.close();
    	}
    	return null;
    }
    private boolean validate(HashMap<String,Object> map ){
    	for(String key : map.keySet()){
    		Object o = map.get(key);
    		if (o instanceof String){
    			if("success".equals((String)o)){
    				;
    			}else{
    				return false;
    			}
    		}else{
    			return false;
    		}
    	}
    	return true;
    }

    private String resultInterface(String sysInfId, String ver, String returnCode, String returnMessage){
    	StringBuffer sb = new StringBuffer();
    	sb.append("<Results sysInfId=\""+sysInfId+"\" ver=\""+ver+"\" >");
    	sb.append("<Result>"+returnCode+"</Result>");
    	sb.append("<ResultMessage>"+returnMessage+"</ResultMessage>");
    	sb.append("</Results>");
    	return sb.toString();
    }
    private String resultInterfaceDelete(String mmiIfId, String id, String returnCode, String returnMessage){
    	return "<Interface mmi_if_id=\""+mmiIfId+"\" id=\""+id+"\" return_code=\""+returnCode+"\" return_message=\""+returnMessage+"\" />";
    }
    private String resultFormatDelete(String mmiIoId, String id, String returnCode, String returnMessage){
    	return "<Format mmi_io_id=\""+mmiIoId+"\" id=\""+id+"\" return_code=\""+returnCode+"\" return_message=\""+returnMessage+"\" />";
    }
	private static String streamToString(InputStream is){
		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
		int r;
		byte[] data = new byte[1024];
		try {
			while((r = is.read(data)) != -1){
				buffer.write(data,0,r);
				
			}
			buffer.flush();
		} catch (IOException e) {
			logger.error(e.getMessage(),e);
			return "";
		}
		String s = new String(buffer.toByteArray());

		return s;
	}


}
