
package com.eactive.eai.rms.bat.loader.controller;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;

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

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
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.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.eactive.eai.common.util.DatetimeUtil;
import com.eactive.eai.rms.bat.loader.service.TransactionLoaderServiceImpl;
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.util.CommonConstants;
import com.eactive.eai.rms.onl.common.util.FileWriteUtil;
import com.eactive.eai.rms.onl.loader.service.RuleDeployJobService;
import com.eactive.eai.rms.onl.loader.vo.RuleDeployJobItemVo;
import com.eactive.eai.rms.onl.loader.vo.RuleDeployJobVo;

@Controller
@RequestMapping(value={"/loaderBAT.do","/loaderBAT.json" } )
public class BatLoaderController implements InterceptorSkipController {

    private static final Logger logger = Logger.getLogger(BatLoaderController.class);
    private static final String resultView ="common/loadResult";
    
    @Autowired 
    private MonitoringContext monitoringContext;

    @Autowired
    @Qualifier("batLoaderService")
    private TransactionLoaderServiceImpl batLoaderService;
    
    @Autowired
	@Qualifier("ruleDeployJobService")
	public RuleDeployJobService ruleDeployJobService;

     /**
     * 형상관리에서 interface을 download한다.
     * *
     * @param request
     * @param response
     * @param schema
     * @return
     * @throws Exception
     */
    @RequestMapping( params ={"cmd=interface","control=download"})
    public ModelAndView interfaceDownLoad(HttpServletRequest request, HttpServletResponse response ,String serviceType , String bzwkDstcd, String fileName ) throws Exception {
        String iomapPath = monitoringContext.getStringProperty(MonitoringContext.IOMAP_DOWNLOAD_PATH);
        String path = iomapPath + serviceType + File.separator + bzwkDstcd + File.separator + FileWriteUtil.INTERFACE + File.separator ;
        boolean isJSONResult=false;
        if (request.getRequestURI().endsWith("json")){
        	isJSONResult = true;
        }
        if (!serviceType.equals("EBT")){
        	HashMap<String,String> result = new HashMap<String,String>();
	    	result.put("status", "error");
	    	result.put("message", "정의 되지 않은 서비스 타입입니다. 받은 서비스 타입="+ serviceType);
	    	if (isJSONResult){
	    		return new ModelAndView("jsonView", result);
	    	}else{
	    		return new ModelAndView(resultView, "result", result);
	    	}
        }

        try{
        	if (fileName != null && serviceType != null) {
        		String[] temp = fileName.split("[.]");
        		String serviceName = temp[0]; 
        		
        		serviceType = DataSourceTypeManager.BAT;
        		request.getSession().setAttribute(CommonConstants.SERVICE_TYPE_KEY, serviceType);
        		DataSourceType dt = DataSourceTypeManager.getDataSourceType(serviceType);
        		if(dt != null){
        			DataSourceContextHolder.setDataSourceType(dt);
        			batLoaderService.interfaceDownLoading(dt,path , serviceName );
        		}
        	}
        	
	        HashMap<String,String> result = new HashMap<String,String>();
	        String status = "success";
	        result.put("status", status);
	        result.put("message", "");
	    	if (isJSONResult){
	    		return new ModelAndView("jsonView", result);
	    	}else{
	    		return new ModelAndView(resultView, "result", result);
	    	}
	        //return new ModelAndView(resultView, "result", result.toString());
        }catch(Exception e){
	    	HashMap<String,String> result = new HashMap<String,String>();
	    	result.put("status", "error");
	    	result.put("message", e.getMessage());
	    	logger.error("interface DownLoad Exception " +e.getMessage(),e);
	    	if (isJSONResult){
	    		return new ModelAndView("jsonView", result);
	    	}else{
	    		return new ModelAndView(resultView, "result", result);
	    	}
        }
    }  
    /**
     * 형상관리에서 interface을 로딩한다.
     * *
     * @param request
     * @param response
     * @param schema
     * @return
     * @throws Exception
     */
    @RequestMapping( params ={"cmd=interface","control=upload"})
    public ModelAndView interfaceLoad(HttpServletRequest request, HttpServletResponse response ,String method, String serviceType , String bzwkDstcd, String fileName ) throws Exception {
    	long sTotalTime = System.currentTimeMillis();
    	//logger.info("------------- INTERFACE --------------");
        boolean isJSONResult=false;
        if (request.getRequestURI().endsWith("json")){
        	isJSONResult = true;
        }
    	
        String iomapPath = "";
        if("aio".equals(method)){
        	iomapPath = monitoringContext.getStringProperty(MonitoringContext.IOMAP_UPLOAD_AIO_PATH);
        }else{
        	iomapPath = monitoringContext.getStringProperty(MonitoringContext.IOMAP_UPLOAD_PATH);
        }
        String savePath = monitoringContext.getStringProperty(MonitoringContext.IOMAP_AFTER_UPLOAD_PATH);
        String subPath = serviceType + File.separator + bzwkDstcd + File.separator + FileWriteUtil.INTERFACE + File.separator;
        String path = iomapPath + subPath ;
        HashMap<String,String> result = new HashMap<String,String>();
        if (!serviceType.equals("EBT")){
        	
	    	result.put("status", "error");
	    	result.put("message", "정의 되지 않은 서비스 타입입니다. 받은 서비스 타입="+ serviceType);
	    	if (isJSONResult){
	    		return new ModelAndView("jsonView", result);
	    	}else{
	    		return new ModelAndView(resultView, "result", result);
	    	}
        }

        try{
        	if (serviceType != null) {
        		serviceType = DataSourceTypeManager.BAT;
        		request.getSession().setAttribute(CommonConstants.SERVICE_TYPE_KEY, serviceType);
        		DataSourceType dt = DataSourceTypeManager.getDataSourceType(serviceType);
        		if(dt != null){
        			//취약점소스 수정 2020.08.27
        			DataSourceContextHolder.setDataSourceType(dt);
        			batLoaderService.insertInterfaceLoading(dt,path , fileName );
        		}
        		
        	}

        	long sTimeForDb = System.currentTimeMillis();
        	long eTimeForDb = System.currentTimeMillis();
            long dbTime = eTimeForDb-sTimeForDb;        
    
        	
	    	if (isJSONResult){
	    		return new ModelAndView("jsonView", result);
	    	}else{
	    		return new ModelAndView(resultView, "result", result);
	    	}        	
//	        return new ModelAndView(resultView, "result", result.toString());
        }catch(Exception e){	    	
	    	result.put("status", "error");
	    	result.put("message", e.getMessage());
	    	logger.error("interface Load Exception " +e.getMessage(),e);
	    	return new ModelAndView(resultView, "result", result);
        }
    } 
   
    /**
     * 형상관리에서 interface 전체를 download한다.
     * *
     * @param request
     * @param response
     * @param schema
     * @return
     * @throws Exception
     */
    @RequestMapping( params ={"cmd=interface","control=downloadall"})
    public ModelAndView interfaceDownLoadAll(HttpServletRequest request, HttpServletResponse response ,String serviceType ) throws Exception {
        boolean isJSONResult=false;
        if (request.getRequestURI().endsWith("json")){
        	isJSONResult = true;
        }
        if (!DataSourceTypeManager.isOnlineForName(serviceType)){
        	HashMap<String,String> result = new HashMap<String,String>();
	    	result.put("status", "error");
	    	result.put("message", "정의 되지 않은 서비스 타입입니다. 받은 서비스 타입="+ serviceType);
	    	if (isJSONResult){
	    		return new ModelAndView("jsonView", result);
	    	}else{
	    		return new ModelAndView(resultView, "result", result);
	    	}
        }

        try{
        	if (serviceType != null) {
        		request.getSession().setAttribute(CommonConstants.SERVICE_TYPE_KEY, serviceType);
        		DataSourceType dt = DataSourceTypeManager.getDataSourceType(serviceType);
        		if(dt != null){
        			DataSourceContextHolder.setDataSourceType(dt);
        			batLoaderService.interfaceDownLoadingAll( dt ,serviceType);
        		}
        		
        	}

	        HashMap<String,String> result = new HashMap<String,String>();
	        String status = "success";
	        result.put("status", status);
	        result.put("message", "");
	    	if (isJSONResult){
	    		return new ModelAndView("jsonView", result);
	    	}else{
	    		return new ModelAndView(resultView, "result", result);
	    	}
	        //return new ModelAndView(resultView, "result", result.toString());
	    }catch(Exception e){
	    	HashMap<String,String> result = new HashMap<String,String>();
	    	result.put("status", "error");
	    	result.put("message", e.getMessage());
	    	logger.error("interface DownLoad All Exception " +e.getMessage(),e);
	    	if (isJSONResult){
	    		return new ModelAndView("jsonView", result);
	    	}else{
	    		return new ModelAndView(resultView, "result", result);
	    	}
	    }  
	    
    }
 
    @RequestMapping(params ={"cmd=interface","control=file-upload"}, method = RequestMethod.POST)
	public ModelAndView uploadInterfaceFile(@RequestParam("file") MultipartFile multipartFile,
			String serviceType, String bzwkDstcd, String cmd) throws Exception {
		return uploadeFile(multipartFile, serviceType, bzwkDstcd, cmd);
	}
    
    private ModelAndView uploadeFile(MultipartFile multipartFile, String serviceType, String bzwkDstcd, String dataType) throws IOException {
		logger.info("### " + dataType + " upload start");

		String iomapPath = monitoringContext.getStringProperty(MonitoringContext.IOMAP_UPLOAD_PATH);
		String subPath = serviceType + File.separator + bzwkDstcd + File.separator + dataType + File.separator;
		String path = iomapPath + subPath ;

		String fullyFileName = FilenameUtils.concat(path, multipartFile.getOriginalFilename());
		File targetFile = new File(fullyFileName);
		try {
			InputStream fileStream = multipartFile.getInputStream();
			FileUtils.copyInputStreamToFile(fileStream, targetFile);
		} catch (IOException e) {
			FileUtils.deleteQuietly(targetFile);
			logger.error(e);
			throw e;
		}

		logger.info("### success " + dataType + " file upload - " + path);
		HashMap<String,String> result = new HashMap<String,String>();
		String status = "success";
		result.put("status", status);
		result.put("message", "");

		return new ModelAndView(resultView, "result", result.toString());
	}
    
    /**
     * 배포된 데이터의 로딩 스케쥴을 등록한다.
     * @param request
     * @param response
     * @param userId
     * @param userIp
     * @param serviceType
     * @param cmTitle
     * @param cmDate
     * @param cmTime
     * @param items
     * @return
     * @throws Exception
     */
	@SuppressWarnings("deprecation")
	@RequestMapping(params = { "cmd=schedule", "control=upload" })
	public ModelAndView scheduleDeployDataApply(HttpServletRequest request, HttpServletResponse response, String userId,
			String userIp, String serviceType, String cmTitle, String cmDate, String cmTime, String items)
			throws Exception {
		try {
			if (StringUtils.isBlank(items)) {
				throw new Exception("No have datas");
			}

			RuleDeployJobVo jobVo = new RuleDeployJobVo();
			jobVo.setJobId(DatetimeUtil.getCurrentTimeMillis());
			jobVo.setFailedCnt(0);
			jobVo.setScheduledDateTime(cmDate + cmTime);
			jobVo.setJobTitle(URLDecoder.decode(cmTitle));
			jobVo.setServiceType(serviceType);
			jobVo.setStatus("standby"); // working, finished, failed
			jobVo.setUserId(userId);
			jobVo.setUserIp(userIp);
			jobVo.setItemList(new ArrayList<RuleDeployJobItemVo>());

			String itemArr[] = items.split("\n");
			for (String itemStr : itemArr) {
				// COP|219036|COP_OPB0210300000_CBS.txt|FEP/COP/layout|layout|
				String item[] = itemStr.split("\\|");
				if (item.length >= 5) {
					RuleDeployJobItemVo itemVo = new RuleDeployJobItemVo();
					itemVo.setBizCode(item[0]);
					itemVo.setFileName(item[2]);
					itemVo.setJobId(jobVo.getJobId());
					itemVo.setRuleType(item[4]);
					jobVo.getItemList().add(itemVo);
				}
			}

			boolean result = true;
			if (System.currentTimeMillis() >= DatetimeUtil.getLongTimeFormat("yyyyMMddHHmmss", cmDate + cmTime)) {
				// 룰정보 적재 및 메모리 로딩
				result = batLoaderService.ruleDataSaveAndLoading(jobVo);
				if (result) {
					jobVo.setStatus("finished");
				} else {
					jobVo.setFailedCnt(jobVo.getFailedCnt() + 1);
				}

				jobVo.setLastJobTime(DatetimeUtil.getCurrentDateTime());
			}

			logger.debug("jobVo=" + jobVo.toString());

			ruleDeployJobService.insert(jobVo);

			if (!result) {
				throw new Exception("Job failed");
			}
		} catch (Exception e) {
			throw new Exception("Job failed:" + e.getMessage());
		}

		return new ModelAndView(resultView, "result", "Rule Data Load Success");
	}
}

