package com.eactive.eai.rms.bat.manage.rule.layoutsync;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

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

import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
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.servlet.View;

import com.eactive.eai.rms.common.base.OnlBaseAnnotationController;
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
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.util.CommonUtil;
import com.eactive.eai.rms.common.util.StringUtils;
import com.eactive.eai.rms.onl.common.util.DateUtil;

@Controller
@RequestMapping("/layoutSyncB.do")
public class BatLayoutSyncManController extends OnlBaseAnnotationController implements InterceptorSkipController {


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

    @Autowired
    @Qualifier("batLayoutSyncManService")
    private BatLayoutSyncManService serviceBean;
    
	/**
	 * xml 형식으로 전달 된 레이아웃을 LayoutVo로 전환
	 * 
	 * @param e
	 * @param msgType
	 * @param loutName
	 * @return
	 * @throws Exception
	 */
	private List<HashMap<String, String>> setLayoutItems(Element e, String adptrCd, String adptrCdSeq, String intfId ) throws Exception {
		List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();

        @SuppressWarnings("unchecked")
		List<Element> items = e.getChildren();
        
        int idx = 0;
        for(Element el : items) {
    		// Layout Item Format (TR08)
        	//Field만 받음
        	if("FIELD".equals(el.getName().toUpperCase()) ) {
	        	HashMap<String, String> item = new HashMap<String, String>();
	
	            String no = el.getAttributeValue("no");
	            String dataType = "0";
	            if( el.getAttributeValue("type") == null ||  "".equals(el.getAttributeValue("type"))) {            	
	            } else if( "VARCHAR".startsWith(el.getAttributeValue("type").toUpperCase()) ) { // Varchar, Number
	            	dataType = "1"; // "String";
	            } else if( "NUMBER".startsWith(el.getAttributeValue("type").toUpperCase()) ) { // Varchar, Number
	            	dataType = "2"; // "Integer";
	            }
	            item.put("adptrCd",    adptrCd);
		        item.put("adptrCdSeq", adptrCdSeq);
		        item.put("intfId",     intfId);
	        	item.put("layoutSeq",  "" + idx++);
	        	item.put("orderSeq",   no);
	        	item.put("colSize",    "" + ("".equals(el.getAttributeValue("len")) ? 0 : Integer.parseInt(el.getAttributeValue("len"))));
	        	item.put("colDepth",   "" + Integer.parseInt(el.getAttributeValue("depth")));
	        	item.put("colDesc",    el.getAttributeValue("desc"));
		        item.put("colDescEng", el.getAttributeValue("id"));
		        item.put("colType",    dataType);
		        item.put("colKind",    "Field");
	
		        logger.info(CommonUtil.getMapString(item, false));
	            list.add(item);	            
        	} /*else {
        		if( el.getChildren() != null && el.getChildren().size() > 0 ) {
	            	list.addAll(setLayoutItems(el, adptrCd, adptrCdSeq, intfId));
	            }
        	}*/
        }  // end FOR
		
		return list;
	}
	
    /**
     * 통합인터페이스 시스템(iim)에서 전문 레이아웃에 대한 INSERT, DELETE 요청
     * *
     * @param request
     * @param response
     * @param schema
     * @return
     * @throws Exception
     */
    @RequestMapping(params = "cmd=Message")
    public View parseMessage(HttpServletRequest request, HttpServletResponse response, String schema) throws Exception {
        UserAccessLogger.log(request, "Layout", "L", "cmd=Message");
        Document rDoc = null;
        Element results = null;
        String  resultS = null;
        ServletInputStream sis = null;

        HashMap<String, String> param = new HashMap<String, String>();
        String recvTime = DateUtil.getDateTime("yyyyMMddHHmmssSS").substring(0, 16);
        if (schema != null) {
        	DataSourceContextHolder.setDataSourceType(DataSourceTypeManager.getDataSourceType(schema));
        }
    	try { 

	    	SAXBuilder builder = new SAXBuilder();
	    	
	        // 응답 전문
	        File res = new File( request.getSession().getServletContext().getRealPath("/WEB-INF/") + "/layout-messagesync-res.xml" );
	        rDoc = builder.build(res);
	        results = rDoc.getRootElement();
	        
	
	    	// 요청 전문
	    	sis = request.getInputStream();	
	        Document doc = builder.build(sis);
//	    	File f = new File( request.getSession().getServletContext().getRealPath("/WEB-INF/") + "/layout-messagesync-sample-req.xml" );
//	        Document doc = builder.build(f);
	        
	        // log 기록 
	        byte[] arg = new byte[request.getContentLength()];
	        int resultSet =0;
	        int total = 0;
	        
	        try {
	        	resultSet = sis.readLine(arg, 0, arg.length);
	        	while(resultSet != -1) {
	        		total += resultSet;
	        		resultSet = sis.readLine(arg, total, 1024);
	        	}
	        	
	        	param.put("RecvData", new String(arg));
	        } catch(Exception e) {
	        	logger.error("MessageSync.err - don't read the XML File - " + new String(arg));
	        }
	        
//	        param.put("logPrcssSeqno", UUIDGenerator.getUUID());
	        // xml 1.1
	        Element message = doc.getRootElement();
	        
	        // Command 확인
	        String command = message.getChild("Header").getChild("Command").getText();
	        
	        Element body = message.getChild("Body").getChild("Layout");
	        String layoutName = body.getChild("id").getText();

	        param.put("ServiceName", message.getChild("Header").getChild("ServiceName").getText());
	        param.put("Command", command);
	        param.put("LoutName", layoutName);
			param.put("RecvAmndHMS", recvTime);
	        param.put("logPrcssSeqno", param.get("ServiceName") + recvTime );
	        
			// adapter 관계 조회
			// : intfId 는 ES06에있는 정보를 사용 ( 1:1관계로 봄  ) 
			// : adapter에 없으면 처리 안함 (선등록을 전제로 함 )
			// : adapter가 여러건인경우 에러처리 함 ( 1:1관계로 봄 )
			// : 다건 에러 확인 , Empty 에러 확인
	        HashMap<String, String> query = new HashMap<String, String>();
	        query.put("layoutKey", layoutName);
	        query.put("Command", command);
			HashMap<String, String> adapter = serviceBean.getAdapterForlayoutKey(query);
			
	        logger.info(layoutName + " command - [" + command +"]");	        
	        if( command.equals("delete") ) {
	        	if(adapter!=null){
	        		if("".equals(adapter.get("adptrCd"))) {
	        		}else {
					param.put("adptrCd",    adapter.get("adptrCd"));
					param.put("adptrCdSeq", adapter.get("adptrCdSeq"));
		        	serviceBean.deleteLayout(param);
	        		}
	        	}
	        } else {
	        	if(adapter!=null){ //취약점소스 수정 2020.08.27
	        		//delete 수행위한 값
					param.put("adptrCd",    adapter.get("adptrCd"));
					param.put("adptrCdSeq", adapter.get("adptrCdSeq"));
	        	}
				
		        String layout = body.getChild("data").getText();
				logger.info(layoutName + " recv Data - [" + layout + "]");
				param.put("RecvData", layout);
				
		        Document doc2 = builder.build(new ByteArrayInputStream(layout.getBytes()));
				Element format = doc2.getRootElement();
		
		        List<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
		        if(adapter!=null){ //취약점소스 수정 2020.08.27
		        	list.addAll(setLayoutItems(format, adapter.get("adptrCd"), adapter.get("adptrCdSeq"), adapter.get("intfId")) );
		        }
		        serviceBean.insertLayout(list, param);  
//		        param.put("PrcssRsltCmnt", CommonUtil.getMapString(returnMap, true));
	        }
	        
	        results.getChild("Result").setText("True");
	        results.getChild("ResultMessage").setText("성공");

	        resultS = StringUtils.toXMLString(rDoc, true);
	        
    	} catch( Exception e ) {
    		//e.printStackTrace();
    		try {
	    		if( results != null ) {
			        results.getChild("Result").setText("False");
			        results.getChild("ResultMessage").setText( e.getMessage() );
			        
			        resultS = StringUtils.toXMLString(rDoc, true);
	    		}
	    		if( param.get("logPrcssSeqno") == null ) {
	    			param.put("logPrcssSeqno", "MessageSync" + recvTime );
	    			param.put("ServiceName", "MessageSync");
	    			param.put("RecvAmndHMS", recvTime);
	    		}
	    		param.put("PrcssRslt", "F");
	    		param.put("PrcssRsltCmnt", e.getMessage());
	    		serviceBean.addLayoutSyncLog(param);
    		} catch(Exception ee) {//취약점소스 수정 2020.08.27
    			logger.error(" error", e);
        		//ee.printStackTrace();
    		}
    	}

		ServletOutputStream sos = null;
    	try {
    		sos = response.getOutputStream();
    		//sos.write(resultS.getBytes());
    		//취약점코드 수정 2019.08.22 SW
    		if(resultS != null){
    			sos.write(resultS.getBytes());
    		}
    	} catch( Exception e ) {
    		logger.error(" error", e); 
    		//e.printStackTrace();  
    	} finally {
    		if( sis != null ) sis.close();
    		if( sos != null ) sos.close();
    	}
    	return null;
    }
}
