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

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

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.onl.adapter.socket.MapComparator;
import com.eactive.eai.rms.onl.manage.adapter.adapter.AdapterDao;

import edu.emory.mathcs.backport.java.util.Collections;

@Service
public class SocketPortManService extends OnlBaseService {

	@Autowired
	private MonitoringContext monitoringContext;

	@Autowired
	private SocketPortDao dao;

	@Autowired
	private AdapterDao adapterDao;

	public HashMap selectList(int startNum, int endNum, HashMap<String, Object> paramMap, String searchOrderType,
			String searchAdptrPort, String searchEaiSevrDstCd, String searchAdptrBzwkNameDesc,
			String searchAdptrBzwkName, Pageable pageable) throws Exception {

		// 전체 목록수 얻기
		String searchUseYn = (String) paramMap.get("searchUseYn");

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

		List<HashMap<String, Object>> list;
		list = dao.selectAllList(paramMap);

		HashMap<String, Object> adapterPortMap = getDBAdapterPort(paramMap);

		// list어댑터 사용여부 체크
		if (list != null) {
			for (HashMap<String, Object> tmp : list) {
				String resvPort = (String) tmp.get("RECVTESTPORT");
				tmp.put("RECVPORTUSEYN", (adapterPortMap.get(resvPort) != null ? adapterPortMap.get(resvPort) : ""));

				String sendPort = (String) tmp.get("SENDTESTPORT");
				tmp.put("SENDPORTUSEYN", (adapterPortMap.get(sendPort) != null ? adapterPortMap.get(sendPort) : ""));

			}
		}

		List<HashMap<String, Object>> filterlist = new ArrayList<HashMap<String, Object>>();
		// 사용여부 체크 조건 있을경우만
		if (list != null && !"".equals(searchUseYn)) {
			for (HashMap<String, Object> tmp : list) {
				if (("Y".equals(searchUseYn) ? !"".equals(tmp.get("RECVPORTUSEYN"))
						: "".equals(tmp.get("RECVPORTUSEYN")))) {
					filterlist.add(tmp);
				}
			}
		}

		HashMap map = new HashMap();
		// map.put("totalCount", (filterlist.size() > totalCount ?filterlist:useCnt) );
		map.put("list", (!"".equals(searchUseYn) ? filterlist : list));

		return map;
	}

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

		String eaiSevrDstCd = (String) paramMap.get("searchEaiSevrDstCd");
		// 모니터링 프라퍼티 인스트정보 가져오기
		String[] adapterInstArr = new String[4];
		String adptPortInst = monitoringContext.getStringProperty(MonitoringContext.ADPT_PORT_INST);

		if (adptPortInst == null) {
			throw new Exception("adpt_port_inst 프라퍼티가 등록되지 않았습니다.");
		}
		adapterInstArr = adptPortInst.split(",");

		// 데이터소스명 지정
		String searchInstNm = adapterInstArr[Integer.parseInt(eaiSevrDstCd) - 1];

		HashMap<String, Object> adapterPortMap = new HashMap<>();
		List<HashMap<String, Object>> adapterPortList = null;
		List<HashMap<String, Object>> adapterPortDMZList = null;

		if (!"4".equals(eaiSevrDstCd)) {
			for (DataSourceType d : DataSourceTypeManager.getOnlineDataSourceTypes()) {
				if (d.getName().equals(searchInstNm)) {
					DataSourceContextHolder.setDataSourceType(d);
					paramMap.put("schemaId", DataSourceTypeManager.getFirstDataSourceType().getSchema());
					adapterPortList = adapterDao.selectadapterPortList(paramMap);
				}
			}

			if ("2".equals(eaiSevrDstCd)) {
				DataSourceType dt = DataSourceTypeManager.getDataSourceType("ZSG");
				DataSourceContextHolder.setDataSourceType(dt);
				String schemaId = "";
				if (dt != null) {
					schemaId = dt.getSchema();
				}
				paramMap.put("schemaId", schemaId);
				adapterPortDMZList = adapterDao.selectadapterPortList(paramMap);
			}
		} else {
			DataSourceType dt = DataSourceTypeManager.getDataSourceType("ISG");
			DataSourceContextHolder.setDataSourceType(dt);
			String schemaId = "";
			if (dt != null) {
				schemaId = dt.getSchema();
			}

			paramMap.put("schemaId", schemaId);
			adapterPortList = adapterDao.selectIsgAdapterPortList(paramMap);

		}

		if (adapterPortDMZList != null) {
			if (adapterPortList != null) {
				adapterPortList.addAll(adapterPortDMZList);
			}
		}

		// 내부, 대외,공동망,일괄 어댑터명,포트 map 만들기
		if (adapterPortList != null) {
			for (HashMap<String, Object> tmp : adapterPortList) {
				adapterPortMap.put((String) tmp.get("PORT"), tmp.get("ADPTRBZWKGROUPNAME"));
			}
		}

		if (!"4".equals(eaiSevrDstCd)) {
			adapterPortList = null;
			// 두건이상 중복포트 어댑터 조회 > 표준 룰 TOBE 어댑터로 가져오기
			for (DataSourceType d : DataSourceTypeManager.getOnlineDataSourceTypes()) {
				if (d.getName().equals(searchInstNm)) {
					DataSourceContextHolder.setDataSourceType(d);
					paramMap.put("schemaId", d.getSchema());
					paramMap.put("chkInstYn", "Y");
					paramMap.put("chkInst1", "{NS_");
					paramMap.put("chkInst2", "{DS_");
					paramMap.put("chkInst3", "{GS_");
					adapterPortList = adapterDao.selectadapterPortList(paramMap);
				}
			}

			// 포트map 한번더
			if (adapterPortList != null) {
				for (HashMap<String, Object> tmp : adapterPortList) {
					adapterPortMap.put((String) tmp.get("PORT"), tmp.get("ADPTRBZWKGROUPNAME"));
				}
			}
		}

		return adapterPortMap;

	}

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

		// 해당서버 어댑터의 사용하는 사용하지 않는 어댑터 리스트 가져오기
		HashMap resultMap = new HashMap();
		List<HashMap<String, Object>> list = dao.selectPortList(paramMap);

		paramMap.put("searchEaiSevrDstCd", paramMap.get("eaiSevrDstCd"));

		HashMap<String, Object> adapterPortMap = getDBAdapterPort(paramMap);
		List<HashMap<String, Object>> filterlist = new ArrayList<HashMap<String, Object>>();
		boolean isUnusedPort = false;

		// list어댑터 사용여부 체크
		if (list != null) {
			for (HashMap<String, Object> tmp : list) {
				String resvPort = (String) tmp.get("RECVTESTPORT");
				tmp.put("RECVPORTUSEYN", (adapterPortMap.get(resvPort) != null ? adapterPortMap.get(resvPort) : ""));
			}

			// 사용하지 않는 어댑터만 가져오기
			for (HashMap<String, Object> tmp : list) {
				if ("".equals(tmp.get("RECVPORTUSEYN"))) {
					filterlist.add(tmp);
				}
			}

			if (filterlist.size() > 0) {
				// 수신포트 sort
				String[] compareParam = { "RECVTESTPORT" };

				MapComparator comp = new MapComparator(compareParam);
				Collections.sort(filterlist, comp);

				for (int i = 0; i < filterlist.size(); i++) {
					HashMap<String, Object> tmp = filterlist.get(i);
					if (tmp.get("RECVTESTPORT") == null) {
						continue;
					}
					if (Integer.parseInt(tmp.get("RECVTESTPORT").toString()) > 40000) {
						resultMap.putAll(tmp);
						isUnusedPort = true;
						break;
					}

				}
			}

		}

		if (!isUnusedPort) { // 사용안하는 어댑터가 없을경우 신규
			resultMap = selectInitPort(paramMap);
		}

		return resultMap;
	}

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

		HashMap resultMap = dao.selectDetail(paramMap);

		return resultMap;
	}

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

		// 내부기준
		int resvTportSt = 41001;
		int plusNumber = 0;

		if ("2".equals(paramMap.get("eaiSevrDstCd"))) {
			plusNumber = 3000;
		} else if ("3".equals(paramMap.get("eaiSevrDstCd"))) {
			plusNumber = 6000;
		} else if ("4".equals(paramMap.get("eaiSevrDstCd"))) {
			plusNumber = 8000;
		}

		resvTportSt += plusNumber;
		int resvRportSt = resvTportSt - 10000;
		int sendTportSt = resvTportSt - ("2".equals(paramMap.get("eaiSevrDstCd")) ? 2000 : 1000);
		int sendRportSt = sendTportSt - 10000;

		paramMap.put("resvTportSt", resvTportSt);
		paramMap.put("resvRportSt", resvRportSt);
		paramMap.put("sendTportSt", sendTportSt);
		paramMap.put("sendRportSt", sendRportSt);

		paramMap.put("resvTportEn", ((resvTportSt + 1000) - 1));
		paramMap.put("resvRportEn", ((resvRportSt + ("2".equals(paramMap.get("eaiSevrDstCd")) ? 2000 : 1000)) - 1));
		paramMap.put("sendTportEn", ((sendTportSt + 1000) - 1));
		paramMap.put("sendRportEn", ((sendRportSt + ("2".equals(paramMap.get("eaiSevrDstCd")) ? 2000 : 1000)) - 1));

		String schemaId = ""; // 취약점소스 수정 2020.08.25
		DataSourceType dt = DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING);
		DataSourceContextHolder.setDataSourceType(dt);

		if (dt != null) {
			schemaId = dt.getSchema();
		}
		paramMap.put("schemaId", schemaId);
		List resultMap = dao.selectInitPort(paramMap);

		HashMap<String, Object> returnMap = new HashMap<String, Object>();

		for (int i = 0; i < resultMap.size(); i++) {
			HashMap<String, Object> tmpMap = new HashMap<String, Object>();
			tmpMap = (HashMap<String, Object>) resultMap.get(i);
			if (i == 0) {
				returnMap.put("RECVTESTPORT", tmpMap.get("ASSIGNPORT"));
			} else if (i == 1) {
				returnMap.put("RECVREALPORT", tmpMap.get("ASSIGNPORT"));
			} else if (i == 2) {
				returnMap.put("SENDTESTPORT", tmpMap.get("ASSIGNPORT"));
			} else {
				returnMap.put("SENDREALPORT", tmpMap.get("ASSIGNPORT"));
			}
		}

		return returnMap;
	}

	public int selectPortdupChk(HashMap paramMap) throws Exception {
		return dao.selectPortdupChk(paramMap);
	}

	public void insert(HashMap paramMap) throws Exception {
		dao.insert(paramMap);
	}

	public void update(HashMap paramMap) throws Exception {
		dao.update(paramMap);
	}

	public void delete(HashMap paramMap) throws Exception {
		dao.delete(paramMap);
	}

	public void deleteList(HashMap<String, Object>[] list) throws Exception {

		HashMap<String, Object> paramMap = null;

		for (HashMap<String, Object> map : list) {
			paramMap = new HashMap<String, Object>();
			paramMap.put("eaiSevrDstCd", map.get("EAISEVRDSTCD"));
			paramMap.put("recvTestPort", map.get("RECVTESTPORT"));
			dao.delete(paramMap);
		}

	}

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

		List list = dao.selectListToExcel(paramMap);

		for (int i = 0; i < list.size(); i++) {
			HashMap<String, Object> tmp = (HashMap<String, Object>) list.get(i);
			String code = (String) tmp.get("EAISEVRDSTCD");
			tmp
					.put("EAISEVRDSTCD",
							("1".equals(code) ? "내부" : "2".equals(code) ? "대외" : "3".equals(code) ? "공동망" : "일괄"));
		}

		HashMap map = new HashMap();
		map.put("list", list);
		return map;
	}

}
