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

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

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

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
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.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.eactive.eai.agent.command.CommonCommand;
import com.eactive.eai.common.util.StringUtil;
import com.eactive.eai.common.util.SystemUtil;
import com.eactive.eai.rms.bat.loader.service.TransactionLoaderServiceImpl;
import com.eactive.eai.rms.bat.manage.rule.schedule.BatScheduleService;
import com.eactive.eai.rms.common.acl.user.BizDao;
import com.eactive.eai.rms.common.base.BatBaseAnnotationController;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.datasource.DataSourceType;
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
import com.eactive.eai.rms.common.login.SessionManager;
import com.eactive.eai.rms.common.spring.LocaleMessage;
import com.eactive.eai.rms.common.util.CamelCaseUtil;
import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.common.util.IpUtil;
import com.eactive.eai.rms.common.vo.JsonPageVo;
import com.eactive.eai.rms.onl.common.sql.BatInterfaceSqlService;
import com.eactive.eai.rms.onl.loader.service.TransactionLoaderService;

@Controller
public class BatInterfaceController extends BatBaseAnnotationController  {

	@Autowired
	@Qualifier("batInterfaceService")
	private BatInterfaceService service;
	
	@Autowired
	private BatScheduleService scheService;
	
	@Autowired
	@Qualifier("bizDao")
	private BizDao bizDao;
	
	@Autowired
	private BatInterfaceSqlService sqlService;
	
	@Autowired
    @Qualifier("batLoaderService") 
    private TransactionLoaderServiceImpl batLoaderService;
	
	@Autowired
	@Qualifier("monitoringContext")
	private MonitoringContext monitoringContext;
	
	@Autowired
	private TransactionLoaderService loaderService;
	
	@Autowired
	@Qualifier("localeMessage")
	private LocaleMessage localeMessage;
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.view")
	public String viewList(HttpServletRequest request, @RequestParam(value = "cmd", required = false ) String cmd ) throws Exception {
		if (cmd == null || "LIST".equals(cmd.toUpperCase())){
			cmd = "";
		}else {
			cmd = CamelCaseUtil.converCamelCase(cmd);
		}
		String path = request.getServletPath();
		return path.split("[.]")[0]+cmd;
	}
	
	/**
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json", params = "cmd=LIST")
	public ModelAndView selectList(HttpServletRequest request,
			JsonPageVo pageVo ,@RequestParam HashMap<String,Object> paramap) throws Exception {
		
		String userid = SessionManager.getUserId(request);
		paramap.put("loginEmpno", userid);
		
		HashMap<String, Object> map = service.selectList( pageVo.getStartNum(), pageVo.getEndNum(), paramap);
		
		pageVo.setTotalCount((Integer)map.get("totalCount"));
		
		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("total"  , pageVo.getTotal());  //전체 페이지수
		resultMap.put("page"   , pageVo.getPage());   //현재 페이지수
		resultMap.put("records", pageVo.getTotalCount());//전체 레코드건수	
		resultMap.put("rows"   , map.get("list"));
		
		ModelAndView modelAndView = new ModelAndView("jsonView",resultMap);		
		return modelAndView;
	}

    @RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=LIST_INIT_COMBO")
    public ModelAndView initCombo( HttpServletRequest request,
            HttpServletResponse response) throws Exception {
    	
    	
		String userId = SessionManager.getUserId(request);
		HashMap<String, Object> paramMap = new HashMap<String, Object>();
		paramMap.put("userId", userId);
 
		//업무구분
		List<HashMap<String, Object>> listBiz = bizDao.selectUserBizCodes(paramMap);
        
        Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("bizList"         , listBiz);
		
		ModelAndView modelAndView = new ModelAndView("jsonView",resultMap);		
		return modelAndView;            
    }   

	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=DETAIL")
	public ModelAndView selectDetail(String intfId) throws Exception {
		
		HashMap<String, Object> map = service.selectDetail(intfId);

		ModelAndView modelAndView = new ModelAndView("jsonView",map);	
		
		return modelAndView;
	}
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=DETAIL_INTF_SCHEDULE")
	public ModelAndView selectDetailIntfSchedule(String intfId) throws Exception {
		
		HashMap<String, Object> map = scheService.selectSchedulesByInterfaceId(intfId);
		
		ModelAndView modelAndView = new ModelAndView("jsonView", map);
		
		return modelAndView;
	}
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=INSERT")
	public ModelAndView insert(HttpServletRequest request,
			HttpServletResponse response,@RequestParam HashMap<String,Object> map) throws Exception {
		
		String userid = SessionManager.getUserId(request);
		map.put("userid", userid);
		service.insert(map);
		
		HashMap<String, Object> broadcastResult = agentUtilService.broadcast(new CommonCommand("com.eactive.eai.agent.scheduler.ReloadBatchInterfaceJobCommand", (String) map.get("intfId")));
		if(!broadcastResult.entrySet().stream().allMatch(entry -> entry.getValue().equals("success"))) {
			String mapString = CommonUtil.getMapString(broadcastResult, false);
			throw new Exception("데이터 수정 완료하였으나 인스턴스 동기화에 실패하였습니다. " + mapString);
		}
		
		ModelAndView modelAndView = new ModelAndView("jsonView",map);	
		return modelAndView;
	}
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=UPDATE")
	public String update(HttpServletRequest request, HttpServletResponse response,@RequestParam HashMap<String,Object> map) throws Exception {
		String userid = SessionManager.getUserId(request);
		map.put("userid", userid);
		service.update(map);
		
		HashMap<String, Object> broadcastResult = agentUtilService.broadcast(new CommonCommand("com.eactive.eai.agent.scheduler.ReloadBatchInterfaceJobCommand", (String) map.get("intfId")));
		if(!broadcastResult.entrySet().stream().allMatch(entry -> entry.getValue().equals("success"))) {
			String mapString = CommonUtil.getMapString(broadcastResult, false);
			throw new Exception("데이터 수정 완료하였으나 인스턴스 동기화에 실패하였습니다. " + mapString);
		}
		return null;
	}
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=DELETE")
	public String delete(HttpServletRequest request,
			HttpServletResponse response, @RequestParam HashMap<String,Object> map ) throws Exception {
		service.delete(map);
		HashMap<String, Object> broadcastResult = agentUtilService.broadcast(new CommonCommand("com.eactive.eai.agent.scheduler.RemoveBatchInterfaceJobCommand", (String) map.get("intfId")));
		if(!broadcastResult.entrySet().stream().allMatch(entry -> entry.getValue().equals("success"))) {
			String mapString = CommonUtil.getMapString(broadcastResult, false);
			throw new Exception("데이터 수정 완료하였으나 인스턴스 동기화에 실패하였습니다. " + mapString);
		}
		return null;
	}
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=LIST_DELETE")
	public String deleteList(HttpServletRequest request, HttpServletResponse response, @RequestParam HashMap<String,Object> map ) throws Exception {

		String[] intfIdList = map.get("intfIdList").toString().split(",");
		Vector<String> intfIdVector = new Vector<>();
		for ( int i=0; i < intfIdList.length; i++ ) {
			String intfId = intfIdList[i];
			intfIdVector.add(intfId);
			HashMap<String, Object> intfIdMap = new HashMap<String,Object>();
			intfIdMap.put("intfId", intfId);
			
			service.delete(intfIdMap);
		}
		
		HashMap<String, Object> broadcastResult = agentUtilService.broadcast(new CommonCommand("com.eactive.eai.agent.scheduler.RemoveBatchInterfaceJobListCommand", intfIdVector));
		if(!broadcastResult.entrySet().stream().allMatch(entry -> entry.getValue().equals("success"))) {
			String mapString = CommonUtil.getMapString(broadcastResult, false);
			throw new Exception("데이터 수정 완료하였으나 인스턴스 동기화에 실패하였습니다. " + mapString);
		}
		
		return null;
	}
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=LIST_DOWNLOAD_SQL")
	public ModelAndView downloadSql(HttpServletRequest request, HttpServletResponse response, String intfId) throws Exception {
		
		String sql = sqlService.batInterfaceSql(intfId);
		
		Map<String, String> resultMap = new HashMap<>();
		resultMap.put("sql", sql);
		
		ModelAndView modelAndView = new ModelAndView("jsonView", resultMap);
		return modelAndView;
	}
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.view",params = "cmd=LIST_FILE_DOWNLOAD")
	public String fileDownload(HttpServletRequest request) throws Exception {
		
		return "/bat/admin/common/filedownload";
	}
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json", params = "cmd=LIST_ADAPTER")
	public ModelAndView adapterList(HttpServletRequest request, JsonPageVo pageVo ,@RequestParam HashMap<String,Object> paramap) throws Exception {
		
		String userid = SessionManager.getUserId(request);
		paramap.put("loginEmpno", userid);
		
		HashMap<String, Object> map = service.adapterList( pageVo.getStartNum(), pageVo.getEndNum(), paramap);
		
		pageVo.setTotalCount((Integer)map.get("totalCount"));
		
		Map<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("total"  , pageVo.getTotal());  //전체 페이지수
		resultMap.put("page"   , pageVo.getPage());   //현재 페이지수
		resultMap.put("records", pageVo.getTotalCount());//전체 레코드건수	
		resultMap.put("rows"   , map.get("list"));
		
		ModelAndView modelAndView = new ModelAndView("jsonView",resultMap);		
		return modelAndView;
	}
	
	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=UPDATE_SND_ADAPTER")
	public String updateSndAdpt(HttpServletRequest request,
			HttpServletResponse response,@RequestParam HashMap<String,Object> map) throws Exception {
		
		service.updateSndAdpt(map);
		
		return null;
	}

	@RequestMapping(value= "/bat/admin/interface/interfaceMan.json",params = "cmd=UPDATE_RCV_ADAPTER")
	public String updateRcvAdpt(HttpServletRequest request,
			HttpServletResponse response,@RequestParam HashMap<String,Object> map) throws Exception {

		service.updateRcvAdpt(map);
		
		return null;
	}
	
	@RequestMapping(value = "/bat/admin/interface/interfaceMan.json", params = "cmd=CLONETOPROD")
	private ModelAndView cloneToProdByEms(HttpServletRequest request, @RequestParam HashMap<String, Object> paramMap)
			throws Exception {
		if (SystemUtil.isProdServer()) {
			throw new Exception("only support dev, stage server");
		}

		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		String userId = SessionManager.getUserId(request);
		String serviceKey = SessionManager.getServiceTypeKey(request);
		String cmTitle = MapUtils.getString(paramMap, "CmTitle", "Deploy Interface/Layout/LayoutMap");
		String cmDate = StringUtil.getNullStr(paramMap.get("CmDate"));
		String cmTime = StringUtil.getNullStr(paramMap.get("CmTime"));
		String listInterfaceId = StringUtil.getNullStr(paramMap.get("ListInterfaceId"));
		String[] interfaceIds = listInterfaceId.split("\\,");
		String downloadPath = monitoringContext.getStringProperty(MonitoringContext.IOMAP_DOWNLOAD_PATH);
		downloadPath = StringUtils.removeEnd(downloadPath, File.separator) + File.separator + serviceKey
				+ File.separator;
		String targetName = monitoringContext.getStringProperty(MonitoringContext.IOMAP_DEPLOY_TARGET_NAME);
		String targetUrl = monitoringContext.getStringProperty(MonitoringContext.IOMAP_DEPLOY_TARGET_URL);
		targetUrl = StringUtils.removeEnd(targetUrl, "/");

		String userIp = IpUtil.getClientIp(request);

		if (logger.isInfoEnabled()) {
			logger.info("-------------------------------------------");
			logger.info("userId=" + userId);
			logger.info("userIp=" + userIp);
			logger.info("serviceKey=" + serviceKey);
			logger.info("cmDate=" + cmDate);
			logger.info("cmTime=" + cmTime);
			logger.info("listInterfaceId=" + listInterfaceId);
			logger.info("downloadPath=" + downloadPath);
			logger.info("targetName=" + targetName); // 스테이징, 운영서버
			logger.info("targetUrl=" + targetUrl); // http://127.0.0.1:20100
			logger.info("-------------------------------------------");
		}

		DataSourceType dt = DataSourceTypeManager.getDataSourceType(serviceKey);
		String items = "";

		// 0. 서브 배포 목록 확보
		HashMap<String, ArrayList<HashMap<String, String>>> listMap = batLoaderService
				.getInterfaceListByInterfaceIds(dt, interfaceIds);

		if (listMap != null && listMap.size() > 0) {
			// 1. 파일 생성
			try {
				for (HashMap<String, String> data : listMap.get(TransactionLoaderServiceImpl.BAT_INTERFACE)) {
					String path = downloadPath + File.separator + data.get("bizCode") + File.separator
							+ TransactionLoaderServiceImpl.BAT_INTERFACE + File.separator;
					batLoaderService.interfaceDownLoading(dt, path,
							StringUtils.removeEnd(data.get("programNm"), ".txt"));
				}
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
				throw new Exception("Make Datafile error:" + e.getMessage());
			}

			// 2. 파일 배포
			try {
				if (StringUtils.isBlank(targetUrl)) {
					throw new Exception("Set EMS property:" + MonitoringContext.IOMAP_DEPLOY_TARGET_URL);
				}

				String url = targetUrl + "/monitoring/loaderBAT.do";
				batLoaderService.deployDataToTargetSystem(url, downloadPath, listMap, serviceKey);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
				throw new Exception("Deploy to target System(" + targetName + ") error:" + e.getMessage());
			}

			items += batLoaderService.parseSimple(serviceKey, "", listMap);
		}

		// 3. 데이터 적용 또는 스케쥴 등록
		try {
			String url = targetUrl + "/monitoring/loaderBAT.do";
			loaderService.scheduleDeployDataApply(url, userId, userIp, serviceKey, cmTitle, cmDate, cmTime, items);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			throw new Exception("Apply DeployData or Apply Schedule error:" + e.getMessage());
		}

		resultMap.put("message", localeMessage.getMessage("ruleDeploy.msg4"));

		ModelAndView modelAndView = new ModelAndView("jsonView", resultMap);
		return modelAndView;
	}
}