package com.eactive.eai.rms.onl.manage.comm.server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eactive.eai.data.entity.onl.server.EAIServer;
import com.eactive.eai.rms.common.base.OnlBaseService;
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.util.CallAgentUtil;
import com.eactive.eai.rms.onl.common.vo.HostInfomationForm;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

@Service
public class AdapterInstManService extends OnlBaseService {

	private static final String AGENT_PAGE_TRACE_STARTSTOP = "adapter_socket2_trace_level.jsp";
	private static final String AGENT_PAGE_STARTSTOP = "adapter_socket2_startstop.jsp";

	private EAIServerService eaiServerService;

	private AdapterGroupService adapterGroupService;

	@Autowired
	public AdapterInstManService(EAIServerService eaiServerService, AdapterGroupService adapterGroupService) {
		this.eaiServerService = eaiServerService;
		this.adapterGroupService = adapterGroupService;
	}

	public List<AdapterInstUI> selectList(String searchAdptrBzwkGroupName, String searchPortNum) {
		return adapterGroupService
				.findAdptrBzwkGroupNamesByPort(searchAdptrBzwkGroupName, searchPortNum)
				.stream()
				.map(AdapterInstUI::new)
				.collect(Collectors.toList());
	}

	public List<Map<String, Object>> selectSubList(String searchAdptGrpName) {
		List<EAIServer> eaiServers = eaiServerService.findAll();
		List<Map<String, Object>> resList = new ArrayList<>();
		List<Map<String, Object>> allList = new ArrayList<>();

		String adptGrp = StringUtils.substringBefore(searchAdptGrpName, "{");

		for (EAIServer eaiServer : eaiServers) {
			fetchDataFromServer(eaiServer, adptGrp, allList);
		}

		filterDataByGroup(adptGrp, allList, resList);

		return resList;
	}

	private void fetchDataFromServer(EAIServer eaiServer, String adptGrp, List<Map<String, Object>> allList) {
		String sIp = eaiServer.getEaisevrip();
		Optional<String> portOptional = adapterGroupService.getSocketMonitorPort(eaiServer.getEaisevrinstncname());

		if (!portOptional.isPresent()) {
			return;
		}
		String port = portOptional.get();
		String url = "http://" + sIp + ":" + port + "/adaptersJson/" + adptGrp;

		try {
			URL u = new URL(url);
			HttpURLConnection conn = (HttpURLConnection) u.openConnection();
			conn.setRequestMethod("GET");

			conn.setConnectTimeout(5000);
			conn.setReadTimeout(5000);

			try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
				parseAndAddData(br, eaiServer, sIp, port, allList);
			} finally {
				conn.disconnect();
			}
		} catch (IOException e) {
			logger.error("", e);
		}
	}

	private void parseAndAddData(BufferedReader br, EAIServer eaiServer, String sIp, String port,
			List<Map<String, Object>> allList) throws IOException {
		String data = br.readLine();
		if (data == null || data.equals("[]")) {
			return;
		}

		data = data.trim();

		ObjectMapper objectMapper = new ObjectMapper();
		List<Map<String, Object>> rows = objectMapper.readValue(data, new TypeReference<List<Map<String, Object>>>() {
		});

		for (Map<String, Object> resMap : rows) {
			resMap.put("EAISEVRINSTNCNAME", eaiServer.getEaisevrinstncname());
			resMap.put("EAISEVRIP", sIp);
			resMap.put("SOCKETPORT", port);

			allList.add(resMap);
		}
	}

	private void filterDataByGroup(String adptGrp, List<Map<String, Object>> allList,
			List<Map<String, Object>> resList) {
		for (Map<String, Object> m : allList) {
			String adptGrpName = (String) m.get("adapterGroupName");
			if (adptGrpName.equalsIgnoreCase(adptGrp)) {
				resList.add(m);
			}
		}
	}

	public Map<String, Object> transactionStartStop(String eaiInstanceName, String startOrStop, String adapterGroupName,
			String adapterName, String level) throws Exception {

		EAIServer eaiServer = eaiServerService.getByEaiSevrInstncName(eaiInstanceName);

		String url = "http://" + eaiServer.getEaisevrip() + ":" + eaiServer.getSevrlsnportname()
				+ HostInfomationForm.WEB_AGENT_CONTEXT_PATH;
		if (level == null) {
			url += AGENT_PAGE_STARTSTOP;
		} else {
			url += AGENT_PAGE_TRACE_STARTSTOP;
		}

		NameValuePair[] postParameters = new NameValuePair[] { new NameValuePair("cmd", startOrStop),
				new NameValuePair("adapterGroupName", adapterGroupName), new NameValuePair("adapterName", adapterName),
				new NameValuePair("level", level) };

		// Agent 를 호출한다.
		CallAgentUtil util = new CallAgentUtil();
		String message = util.getAgentDataToString(url, postParameters);

		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("message", message);
		return resultMap;
	}

}
