package com.eactive.eai.rms.onl.manage.adapter.adapterchange;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.eactive.eai.agent.command.Command;
import com.eactive.eai.agent.command.CommonCommand;
import com.eactive.eai.common.util.HttpUtil;
import com.eactive.eai.data.entity.onl.server.EAIServer;
import com.eactive.eai.rms.common.acl.user.BizDao;
import com.eactive.eai.rms.common.acl.user.UserDao;
import com.eactive.eai.rms.common.base.OnlBaseService;
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.spring.BaseController;
import com.eactive.eai.rms.common.util.CommonUtil;
import com.eactive.eai.rms.data.entity.onl.adapter.AdapterGroupService;
import com.eactive.eai.rms.data.entity.onl.server.EAIServerService;
import com.eactive.eai.rms.onl.common.exception.BizException;
import com.eactive.eai.rms.onl.common.util.DataSetUtil;
import com.eactive.eai.rms.onl.common.vo.HostInfomationForm;
import com.eactive.eai.rms.onl.manage.adapter.adapter.AdapterDao;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service("adapterChangeService")
public class AdapterChangeService extends OnlBaseService {

	private static final String AGENT_PAGE_STATUS = "adapter_socket2_agent1.jsp";

	@Autowired
	@Qualifier("adapterDao")
	private AdapterDao adapterDao;

	@Autowired
	private AdapterChangeUserLogDao adapterChangeUserLogDao;

	@Autowired
	@Qualifier("bizDao")
	private BizDao bizDao;

	@Autowired
	@Qualifier("userDao")
	private UserDao userDao;

	@Autowired
	private MonitoringContext monitoringContext;

	@Autowired
	private AdapterGroupService adapterGroupService;
	
	@Autowired
	private EAIServerService eaiServerService;

	public List selectChannelList(HashMap param) throws Exception {
		return adapterDao.selectChannelList(param);
	}

	public void updateAdaptersForSimYn(HashMap paramMap) throws Exception {
		adapterDao.updateAdaptersForSimYn(paramMap);
	}

	public void updateChangeAdapter(HashMap paramMap) throws Exception {
		adapterDao.updateChangeAdapter(paramMap);
	}

	public int selectChgAdapterUserCount(HashMap paramMap) throws Exception {
		return adapterChangeUserLogDao.selectChgAdapterUserCount(paramMap);
	}

	public List<HashMap<String, String>> selectChgAdapterUserInfo(HashMap paramMap) throws Exception {

		return adapterChangeUserLogDao.selectChgAdapterUserInfo(paramMap);
	}

	public void insertAdapterUserInfo(HashMap<String, String> paramMap) throws Exception {

		String serviceType = paramMap.get("serviceType");
		String adapterGroupName = paramMap.get("ADPTRBZWKGROUPNAME");
		String devUseYn = paramMap.get("DEVUSEYN");
		String testUseYn = paramMap.get("TESTUSEYN");
		String beforeDevTest = paramMap.get("MODFIBFEAISEVRNAME");
		String after_DevTest = "D" + devUseYn + "T" + testUseYn;

		HashMap<String, String> queryMap = new HashMap<>();
		queryMap.put("logServiceType", serviceType);
		queryMap.put("ADPTRBZWKGROUPNAME", adapterGroupName);
		queryMap.put("MODFIBFEAISEVRNAME", beforeDevTest);
		queryMap.put("MODFIAFEAISEVRNAME", after_DevTest);

		adapterChangeUserLogDao.insertAdapterUserInfo(queryMap);
	}

	public List<HashMap<String, Object>> selectUserBizCodes(HashMap<String, Object> paramMap) {
		return bizDao.selectUserBizCodes(paramMap);
	}

	public List<HashMap<String, Object>> selectChgAdptUserBizCodes(HashMap<String, Object> paramMap) {
		return bizDao.selectChgAdptUserBizCodes(paramMap);
	}

	public HashMap selectAdapterList(int startNum, int endNum, HashMap<String, Object> paramMap) throws Exception {

		// 전체 목록수 얻기
		int totalCount = adapterDao.selectListCount(paramMap);

		paramMap.put("startNum", startNum);// 시작 record
		paramMap.put("endNum", endNum);// 끝 record

		List list = adapterDao.selectList(paramMap);

		HashMap map = new HashMap();

		map.put("totalCount", totalCount);
		map.put("list", list);

		return map;
	}

	public List<HashMap<String, Object>> selectChgAdapterList(HashMap<String, Object> paramMap) throws Exception {
		return adapterDao.selectChgAdapterList(paramMap);
	}

	public int selectChgAdptUserBizCode(HashMap paramMap) throws Exception {
		return bizDao.selectChgAdptUserBizCode(paramMap);
	}

	public List<HashMap<String, Object>> getTest_adapterList(HashMap<String, Object> paramMap) throws Exception {

		Map<String, String> urlParameter = new HashMap<>();
		urlParameter.put("cmd", "LIST");
		urlParameter.put("serviceType", (String) paramMap.get("serviceType"));

		String url = monitoringContext.getStringProperty(MonitoringContext.ADPT_CHG_TEST_URL);

		String testAdapterResponse = HttpUtil.httpCall(url, "GET", "UTF-8", urlParameter);

		if (testAdapterResponse == null) {
			throw new Exception("Test adapter list response is null. Please check url parameter : " + url);
		}

		ObjectMapper jacksonMapper = new ObjectMapper();
		HashMap<String, List<HashMap<String, Object>>> readValue = jacksonMapper.readValue(testAdapterResponse,
				HashMap.class);

		return readValue.get("response");
	}

	public String reloadAdapter(String adapterGroupName) throws Exception {

		Command command = new CommonCommand("com.eactive.eai.agent.adapter.ReloadAdapterGroupCommand",
				adapterGroupName);

		try {

			return CommonUtil.getMapString(agentUtilService.broadcast(command), true);
		} catch (Exception e) {
			logger.error("AdapterChange Command Error : " + e.getMessage());
			throw e;
		}

	}

	public void sendAdapterChangeOperation(HashMap<String, String> paramMap) throws Exception {

		String url = monitoringContext.getStringProperty(MonitoringContext.ADPT_CHG_TEST_URL);
		Map<String, String> urlParameter = new HashMap<>();
		urlParameter.putAll(paramMap);
		urlParameter.put("cmd", "RELOAD_SEND_COMMAND");

		String response = HttpUtil.httpCall(url, "GET", "UTF-8", urlParameter);

		ObjectMapper jacksonMapper = new ObjectMapper();

		HashMap<String, String> readValue = jacksonMapper.readValue(response, HashMap.class);

		switch (readValue.get("response")) {
		case AdapterChangeConstants.SUCCESS:
			break;
		case AdapterChangeConstants.FAIL_UPDATE:
			throw new Exception("Send adapter change operation failed : FAIL_UPDATE TEST EMS Database");
		case AdapterChangeConstants.FAIL_RELOAD:
			throw new Exception("Send adapter change operation failed : FAIL_RELOAD TEST FEP Command");
		case AdapterChangeConstants.FAIL_UNDEFINED:
			throw new Exception("Send adapter change operation failed : FAIL_UNDEFINED Error");
		}

	}

	public String adapterStartStop(HashMap<String, String> map) throws Exception {

		String message = "";

		String adapterGroupName = map.get("ADPTRBZWKGROUPNAME");
		String devUseYn = map.get("DEVUSEYN");
		String testUseYn = map.get("TESTUSEYN");

		logger.info("AdapterGroupName : " + adapterGroupName);
		logger.info("DevUseYn  : " + devUseYn);
		logger.info("TestUseYn : " + testUseYn);

		/** 기사용중인 어댑터의 종료가 선행되어야함 **/
		if (devUseYn.equals("1") && testUseYn.equals("0")) {

			sendAdapterChangeOperation(map);

			map.put("ADPTRUSEYN", devUseYn);
			updateChangeAdapter(map);

			try {

				reloadAdapter(adapterGroupName);

			} catch (Exception e) {

				logger.error("Adapter Change Command Error : " + e.getMessage());
				throw e;
			}

			message = start_stop_success_message(adapterGroupName, devUseYn, testUseYn);

		} else if (devUseYn.equals("0") && testUseYn.equals("1")) {

			map.put("ADPTRUSEYN", devUseYn);
			updateChangeAdapter(map);

			try {

				reloadAdapter(adapterGroupName);

			} catch (Exception e) {

				logger.error("Adapter Change Command Error : " + e.getMessage());
				throw e;
			}

			sendAdapterChangeOperation(map);

			message = start_stop_success_message(adapterGroupName, devUseYn, testUseYn);

		} else if (devUseYn.equals("0") && testUseYn.equals("0")) {

			sendAdapterChangeOperation(map);

			map.put("ADPTRUSEYN", devUseYn);
			updateChangeAdapter(map);

			try {

				reloadAdapter(adapterGroupName);

			} catch (Exception e) {

				logger.error("Adapter Change Command Error : " + e.getMessage());
				throw e;
			}

			message = start_stop_success_message(adapterGroupName, devUseYn, testUseYn);

		}

		return message;
	}

	private String start_stop_success_message(String adapterGroupName, String devUseYn, String testUseYn) {

		StringBuilder sb = new StringBuilder();

		sb.append("어댑터 전환 성공\n");
		sb.append("어댑터 명 : ");
		sb.append(adapterGroupName);
		sb.append("\n");
		sb.append("개발 : ");
		sb.append(devUseYn);
		sb.append("\n");
		sb.append("테스트 : ");
		sb.append(testUseYn);

		return sb.toString();
	}

	public List<HashMap<String, Object>> getLocalStatusList(HashMap<String, Object> paramMap,
			String serverType) {

		List<HashMap<String, Object>> result = new ArrayList<>();

		String serviceType = (String) paramMap.get("serviceType");
		String searchAdapterGroup = (String) paramMap.get("searchAdapterGroup");

		DataSourceType datasource = DataSourceTypeManager.getDataSourceType(serviceType);
		DataSourceContextHolder.setDataSourceType(datasource);

		DataSetUtil gUtil = new DataSetUtil();

		if (adapterGroupService.existsById(searchAdapterGroup)) {

			List<EAIServer> serverList = eaiServerService.selectEaiServerIpList();

			if (serverList.isEmpty()) {
				throw new BizException("서버리스트가 없습니다.");
			}

			List<String> urls = new ArrayList<>();

			for (EAIServer serverMap : serverList) {
				StringBuilder sb = new StringBuilder();

				sb.append("http://").append(serverMap.getEaisevrip()).append(":")
						.append(serverMap.getSevrlsnportname())
						.append(HostInfomationForm.WEB_AGENT_CONTEXT_PATH).append(AGENT_PAGE_STATUS)
						.append("?adapterType=SOC").append("&eaiSvrInstNm=")
						.append(serverMap.getEaisevrinstncname()).append("&adapterGroupName=")
						.append(searchAdapterGroup);

				String url = sb.toString();
				urls.add(url);
				
				if (logger.isInfoEnabled()) {
					logger.info(url);
				}
			}

			HashMap<String, String> filter = new HashMap<>();

			if (!"".equals(searchAdapterGroup)) {
				filter.put("AdptrBzwkGroupName", searchAdapterGroup);
			}

			gUtil.setFilter(filter);
			result = gUtil.flushXmlToClient(urls);

			for (HashMap<String, Object> tmp : result) {
				tmp.put("EaiServerName", serverType);
			}
		}

		return result;
	}

	public List<HashMap<String, Object>> getTestStatusList(HashMap<String, Object> paramMap) throws Exception {

		String url = monitoringContext.getStringProperty(MonitoringContext.ADPT_CHG_TEST_URL);

		Map<String, String> urlParameter = new HashMap<>();
		urlParameter.put("cmd", "STATUS");
		urlParameter.put("serviceType", (String) paramMap.get("serviceType"));
		urlParameter.put("searchAdapterGroup", (String) paramMap.get("searchAdapterGroup"));

		String test_adatperStatus_response = HttpUtil.httpCall(url, "GET", "UTF-8", urlParameter);

		if (test_adatperStatus_response == null) {
			throw new Exception("Test adapter status response is null. Please check url parameter : " + url);
		}

		ObjectMapper jacksonMapper = new ObjectMapper();
		HashMap<String, List<HashMap<String, Object>>> readValue = jacksonMapper.readValue(test_adatperStatus_response,
				HashMap.class);

		return readValue.get("response");
	}

	public List<HashMap<String, Object>> selectChgCmdAdapterList(HashMap<String, Object> paramMap) throws Exception {
		return adapterDao.selectChgCmdAdapterList(paramMap);
	}

}
