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

import java.io.File;
import java.util.HashMap;

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.servlet.ModelAndView;

import com.eactive.eai.agent.command.Command;
import com.eactive.eai.agent.command.CommonCommand;
import com.eactive.eai.rms.bap.loader.service.TransactionBAPService;
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.onl.common.service.AgentUtilService;
import com.eactive.eai.rms.onl.common.util.DateUtil;
import com.eactive.eai.rms.onl.common.util.FileWriteUtil;
import com.eactive.eai.rms.onl.common.util.SimpleFileUtils;

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

	private static final Logger logger = Logger.getLogger(LoaderBAPController.class);
	private static final String resultView = "common/loadResult";

	@Autowired
	private MonitoringContext monitoringContext;

	@Autowired
	@Qualifier("loaderBAPService")
	private TransactionBAPService loaderBAPService;

	/** The agentUtil service. */
	@Autowired
	@Qualifier("bapAgentUtilService")
	public AgentUtilService agentUtilService;

	/**
	 * 형상관리에서 layout을 로딩한다. *
	 * 
	 * @param request
	 * @param response
	 * @param schema
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = { "cmd=fileinfo", "control=upload" })
	public ModelAndView fileInfoLoad(HttpServletRequest request, HttpServletResponse response, String method,
			String serviceType, String bzwkDstcd, String fileName) throws Exception {
		long sTotalTime = System.currentTimeMillis();
		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.LAYOUT + File.separator;
		String subPath = serviceType + File.separator + bzwkDstcd + File.separator;
		String path = iomapPath + subPath;

//        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("BAP");
				if (dt != null) { // 취약점소스 수정 2020.08.27
					DataSourceContextHolder.setDataSourceType(dt);
					loaderBAPService.insertFileInfoLoading(dt, path, fileName);
				}
			}
			// logger.info("-----layout UpLoad Db Start-----");
			long sTimeForDb = System.currentTimeMillis();
			long eTimeForDb = System.currentTimeMillis();
			long dbTime = eTimeForDb - sTimeForDb;

			// logger.info("-----layout Upload Mem Start-----");
			long sTimeForMem = System.currentTimeMillis();
			HashMap result = syncResult(new CommonCommand("com.eactive.eai.agent.transformer.ReloadLayoutCommand"),
					fileName);
			long eTimeForMem = System.currentTimeMillis();
			long memTime = eTimeForMem - sTimeForMem;
			// logger.info("2:Memory Processed Time : " + (eTimeForMem-sTimeForMem));

			// HashMap result = new HashMap();
			// result.put("status", "success");

			long eTotalTime = System.currentTimeMillis();
			long totTime = eTotalTime - sTotalTime;
			// logger.info(" FILENAME DB MEM TOTAL" );
			logger.info("LoaderLogging	Layout     " + fileName + "          " + dbTime + "         " + memTime
					+ "          " + totTime);

			// file move
			if (!((String) result.get("status")).equals("error")) {
				String today = DateUtil.getDateTime("yyyy-MM-dd");
				String newPath = savePath + today + File.separator + subPath;
				try {
					Boolean isMoved = SimpleFileUtils.moveFile(path, newPath, fileName, fileName);
					if (isMoved) {
						logger.info(fileName + " is moved to " + newPath);
					} else {
						logger.info(fileName + " is moved NOT to " + newPath);
					}
				} catch (Exception e) {
					logger.info("Failed to move File");
				}
			}
			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 result = new HashMap();
			result.put("status", "error");
			result.put("message", e.getMessage());
			logger.error("fileInfo Load Exception " + e.getMessage(), e);
			if (isJSONResult) {
				return new ModelAndView("jsonView", result);
			} else {
				return new ModelAndView(resultView, "result", result);
			}
		}

	}

	private HashMap syncResult(Command command, String fileName) throws Exception {
		// layout 동기화 service 에는 transaction 때문에 문제의 소지가 있음
		HashMap receive = new HashMap();
		HashMap result = new HashMap();

		if (fileName != null) {
			String[] name = fileName.split("\\.");
			if (name.length > 0 && name[0] != null) {
				command.setArgs(name[0]);
				receive = agentUtilService.broadcast(command);
			}

			String status = "success";
			for (Object o : receive.keySet()) {
				String key = (String) o;
				if (receive.get(key) == null || !"success".equals(receive.get(key))) {
					status = "error";
					break;
				}
			}

			result.put("status", status);
			result.put("message", receive.toString());

			if (logger.isInfoEnabled()) {
				logger.info(this.getClass().toString() + "] command = " + command.getClass().toString() + " fileName="
						+ fileName + " status = " + status + " message = " + receive.toString());
			}
		}

		return result;
	}

	/**
	 * 형상관리에서 파일정보를 download한다. *
	 * 
	 * @param request
	 * @param response
	 * @param schema
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = { "cmd=fileinfo", "control=download" })
	public ModelAndView fileInfoDownLoad(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 + "fileinfo"
				+ File.separator;
		boolean isJSONResult = false;
		if (request.getRequestURI().endsWith("json")) {
			isJSONResult = true;
		}

		// TODO HD 에러저리 확인 적용 필요
//        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 (fileName != null && serviceType != null) {
				
				String[] temp = fileName.split("[.]");
				String serviceName = temp[0];

				//request.getSession().setAttribute(CommonConstants.SERVICE_TYPE_KEY, serviceType);
				DataSourceType dt = DataSourceTypeManager.getDataSourceType("BAP");
				if (dt != null) {
					DataSourceContextHolder.setDataSourceType(dt);
					
					loaderBAPService.fileInfoDownLoading(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.toString());
			}
		} catch (Exception e) {
			HashMap<String, String> result = new HashMap<String, String>();
			result.put("status", "error");
			result.put("message", e.getMessage());
			logger.error("layout DownLoad Exception " + e.getMessage(), e);
			if (isJSONResult) {
				return new ModelAndView("jsonView", result);
			} else {
				return new ModelAndView(resultView, "result", result);
			}
		}

	}

	/**
	 * 형상관리에서 table을 로딩한다. *
	 * 
	 * @param request
	 * @param response
	 * @param schema
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = { "cmd=admin", "control=upload" })
	public ModelAndView adminLoad(HttpServletRequest request, HttpServletResponse response, String serviceType,
			String bzwkDstcd, String fileName) throws Exception {

		String iomapPath = monitoringContext.getStringProperty(MonitoringContext.IOMAP_UPLOAD_PATH);
		String path = iomapPath + serviceType + File.separator + bzwkDstcd + File.separator + FileWriteUtil.ADMIN
				+ File.separator;
		boolean isJSONResult = false;
		if (request.getRequestURI().endsWith("json")) {
			isJSONResult = true;
		}
		if (serviceType != null && !DataSourceTypeManager.isOnlineForName("BAP")) {
			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("BAP");
				if (dt != null) {// 취약점소스 수정 2020.08.25
					DataSourceContextHolder.setDataSourceType(dt);
					loaderBAPService.insertTableLoading(dt, path, fileName);
				}

			}

			HashMap result = new HashMap();
			result.put("status", "success");
			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 result = new HashMap();
			result.put("status", "error");
			result.put("message", e.getMessage());
			logger.error("admin Load Exception " + e.getMessage(), e);
			if (isJSONResult) {
				return new ModelAndView("jsonView", result);
			} else {
				return new ModelAndView(resultView, "result", result);
			}
		}
	}

	/**
	 * 형상관리에서 table을 download한다. *
	 * 
	 * @param request
	 * @param response
	 * @param schema
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(params = { "cmd=admin", "control=download" })
	public ModelAndView adminDownLoad(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.ADMIN
				+ File.separator;
		boolean isJSONResult = false;
		if (request.getRequestURI().endsWith("json")) {
			isJSONResult = true;
		}
		if (!DataSourceTypeManager.isOnlineForName("BAP")) {
			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 tableName = temp[0];

				//request.getSession().setAttribute(CommonConstants.SERVICE_TYPE_KEY, serviceType);
				DataSourceType dt = DataSourceTypeManager.getDataSourceType("BAP");
				if (dt != null) {
					DataSourceContextHolder.setDataSourceType(dt);
					loaderBAPService.tableDownLoading(dt, path, tableName);
				}

			}

			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("admin DownLoad Exception " + e.getMessage(), e);
			if (isJSONResult) {
				return new ModelAndView("jsonView", result);
			} else {
				return new ModelAndView(resultView, "result", result);
			}
		}
	}
}
