package com.eactive.eai.adapter.socket2.config;

import com.eactive.eai.adapter.AdapterGroupVO;
import com.eactive.eai.adapter.AdapterManager;
import com.eactive.eai.adapter.AdapterVO;
import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter;
import org.apache.mina.common.IoSession;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

public class MonitoringUtil {
	static final SocketAdapterManager manager = SocketAdapterManager.getInstance();
	static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

	private MonitoringUtil() {

	}

	public static String[][] adapterStatus(String adapterGroupName) throws Exception {
		Vector<String[]> list = new Vector<>();
		ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups();
		AdapterManager gmanager = AdapterManager.getInstance();

		if (existsAdapterGroup(adapterGroupName)) {
			AdapterGroupVO gvo = gmanager.getAdapterGroupVO(adapterGroupName);
			ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName);
			for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) {
				String[] info = new String[12];
				ISocketAdapter adapter = (ISocketAdapter) ee.nextElement();
				info[0] = adapterGroupName;
				info[1] = adapter.getContext().getAdapterName();
				info[2] = adapter.getContext().getDescription();
				info[3] = adapter.getContext().getBoundUsage();
				info[4] = String.valueOf(getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName()));
				info[5] = ""; // gvo.getRealTimeGroupName();
				info[6] = "1"; // gvo.isRealTimeBzwkFlag() ? "1" : "0";
				info[7] = adapter.getState().toString();
				info[8] = gvo.getKesaUseYn();
				info[9] = gvo.getTestMasterYn();
				info[10] = gvo.getAdptrNickName();
				info[11] = gvo.getCompanyCodeData();
				list.add(info);
			}
		}

		String[][] adapters = new String[list.size()][5];
		for (int i = 0; i < list.size(); i++) {
			adapters[i] = list.get(i);
		}
		return adapters;
	}

	public static String[][] adapterList1() throws Exception {
		Vector<String[]> list = new Vector<>();
		ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups();
		AdapterManager gmanager = AdapterManager.getInstance();
		for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) {
			String adapterGroupName = (String) e.nextElement();
			if (!existsAdapterGroup(adapterGroupName)) {
				continue;
			}
			AdapterGroupVO gvo = gmanager.getAdapterGroupVO(adapterGroupName);
			ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName);
			for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) {
				String[] info = new String[12];
				ISocketAdapter adapter = (ISocketAdapter) ee.nextElement();
				info[0] = adapterGroupName;
				info[1] = adapter.getContext().getAdapterName();
				info[2] = adapter.getContext().getDescription();
				info[3] = adapter.getContext().getBoundUsage();
				info[4] = String.valueOf(getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName()));
				info[5] = ""; // gvo.getRealTimeGroupName();
				info[6] = "1"; // gvo.isRealTimeBzwkFlag() ? "1" : "0";
				info[7] = adapter.getState().toString();
				info[8] = gvo.getKesaUseYn();
				info[9] = gvo.getTestMasterYn();
				info[10] = gvo.getAdptrNickName();
				info[11] = gvo.getCompanyCodeData();
				list.add(info);
			}
		}

		String[][] adapters = new String[list.size()][5];
		for (int i = 0; i < list.size(); i++) {
			adapters[i] = list.get(i);
		}
		return adapters;
	}

	public static String[][] adapterList2() throws Exception {
		Vector<String[]> list = new Vector<String[]>();
		ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups();
//		AdapterManager gmanager = AdapterManager.getInstance();
		for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) {
			String adapterGroupName = (String) e.nextElement();
			if (!existsAdapterGroup(adapterGroupName)) {
				continue;
			}
//	    	AdapterGroupVO gvo = gmanager.getAdapterGroupVO(adapterGroupName);
			ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName);
			for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) {
				String[] info = new String[11];
				ISocketAdapter adapter = (ISocketAdapter) ee.nextElement();
				info[0] = adapterGroupName;
				info[1] = adapter.getContext().getAdapterName();
				info[2] = adapter.getContext().getDescription();
				info[3] = String.valueOf(adapter.getContext().getMaxConnection());
				info[4] = String.valueOf(adapter.getSessionPool().peekSize());
				info[5] = String.valueOf(adapter.getMessageSend());
				info[6] = String.valueOf(adapter.getMessageRecv());
				info[7] = String.valueOf(adapter.getRecentErrorCount());
				info[8] = String.valueOf(getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName()));
				info[9] = ""; // gvo.getRealTimeGroupName();
				info[10] = "1"; // gvo.isRealTimeBzwkFlag() ? "1" : "0";
				list.add(info);
			}
		}

		String[][] adapters = new String[list.size()][7];
		for (int i = 0; i < list.size(); i++) {
			adapters[i] = list.get(i);
		}
		return adapters;
	}

	public static String[][] adapterInstList() throws Exception {
		Vector<String[]> list = new Vector<String[]>();
		ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups();
//		AdapterManager gmanager = AdapterManager.getInstance();
		for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) {
			String adapterGroupName = (String) e.nextElement();
			if (!existsAdapterGroup(adapterGroupName)) {
				continue;
			}
//	    	AdapterGroupVO gvo = gmanager.getAdapterGroupVO(adapterGroupName);
			ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName);
			for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) {
				String[] info = new String[6];
				ISocketAdapter adapter = (ISocketAdapter) ee.nextElement();
				info[0] = adapterGroupName;
				info[1] = adapter.getContext().getAdapterName();
				info[2] = adapter.getContext().getDescription();
				info[3] = String.valueOf(adapter.getMessageSend());
				info[4] = String.valueOf(adapter.getMessageRecv());
				info[5] = String.valueOf(adapter.getRecentErrorCount());
				list.add(info);
			}
		}

		String[][] adapters = new String[list.size()][6];
		for (int i = 0; i < list.size(); i++) {
			adapters[i] = list.get(i);
		}
		return adapters;
	}

	public static String[][] adapterTraceLevel() throws Exception {
		Vector<String[]> list = new Vector<String[]>();
		ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups();
		for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) {
			String adapterGroupName = (String) e.nextElement();
			if (!existsAdapterGroup(adapterGroupName)) {
				continue;
			}
			ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName);
			for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) {
				String[] info = new String[5];
				ISocketAdapter adapter = (ISocketAdapter) ee.nextElement();
				info[0] = adapterGroupName;
				info[1] = adapter.getContext().getAdapterName();
				info[2] = adapter.getContext().getDescription();
				info[3] = String.valueOf(getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName()));
				info[4] = String.valueOf(adapter.getContext().getTraceLevel());
				list.add(info);
			}
		}

		String[][] adapters = new String[list.size()][4];
		for (int i = 0; i < list.size(); i++) {
			adapters[i] = list.get(i);
		}
		return adapters;
	}

	public static String[] adapterError(String adapterGroupName, String adapterName) throws Exception {
//		StringBuffer sb = new StringBuffer();
		ISocketAdapter adapter = manager.getSocketAdapter(adapterGroupName + "." + adapterName);
		if (adapter == null)
			return new String[0];

		return adapter.getRecentErrors();
	}

	public static String[][] sessionList(String adapterGroupName) throws Exception {
		Vector<String[]> list = new Vector<String[]>();
		ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups();
		ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName);

		if (adapters == null || !existsAdapterGroup(adapterGroupName)) {
			return new String[0][14];
		}

		for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) {
			ISocketAdapter adapter = (ISocketAdapter) ee.nextElement();
			for (Iterator iter = adapter.getSessionPool().iterator(); iter.hasNext();) {
				String[] info = new String[14];
				IoSession session = (IoSession) iter.next();
				info[0] = adapterGroupName;
				info[1] = adapter.getContext().getAdapterName();
				info[2] = adapter.getContext().getDescription();
				info[3] = adapter.getContext().getBwkClsCd();
				info[4] = adapter.getContext().getBoundUsage();
				info[5] = adapter.getContext().getSocketType();
				info[6] = adapter.getContext().getAckSupport();
				info[7] = session.getLocalAddress().toString();
				info[8] = session.getRemoteAddress().toString();
				info[9] = String.valueOf(session.getWrittenMessages());
				info[10] = String.valueOf(session.getReadMessages());
				info[11] = getDateTime(session.getCreationTime());
				info[12] = getDateTime(session.getLastIoTime());
				info[13] = session.toString();
				list.add(info);
			}
		}

		String[][] sessions = new String[list.size()][13];
		for (int i = 0; i < list.size(); i++) {
			sessions[i] = list.get(i);
		}
		return sessions;
	}

	public static void adapterStart(String adapterGroupName, String adapterName) throws Exception {
		SocketAdapterManager.getInstance().start(adapterGroupName, adapterName);
	}

	public static void adapterStop(String adapterGroupName, String adapterName) throws Exception {
		SocketAdapterManager.getInstance().stop(adapterGroupName, adapterName);
	}

	public static void adapterChangeTraceLevel(String adapterGroupName, String adapterName, int traceLevel)
			throws Exception {
		ISocketAdapter adapter = SocketAdapterManager.getInstance().getSocketAdapter(adapterGroupName, adapterName);
		if (adapter != null)
			adapter.getContext().setTraceLevel(traceLevel);
	}

//	public static void sessionClose(String adapterGroupName, String adapterName, String remoteAddress, String localAddress) throws Exception {
//		ISocketAdapter adapter = SocketAdapterManager.getInstance().getSocketAdapter(adapterGroupName, adapterName);
//		IoSession session = adapter.getSessionPool().find(remoteAddress, localAddress);
//		if (session != null)
//			session.close();
//	}

	public static void sessionClose(String adapterGroupName, String sessionName) throws Exception {
//		Vector<String[]> list = new Vector<String[]>();
		ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups();
		ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName);

		for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) {
			ISocketAdapter adapter = (ISocketAdapter) ee.nextElement();
			for (Iterator iter = adapter.getSessionPool().iterator(); iter.hasNext();) {
				IoSession session = (IoSession) iter.next();
				if (sessionName.equals(session.toString())) {
					session.close();
					return;
				}
			}
		}
	}

	private static boolean getAdapterStatus(String adapterGroupName, String adapterName) {
		AdapterManager manager = AdapterManager.getInstance();
		AdapterVO vo = manager.getAdapterVO(adapterGroupName, adapterName);
		if (vo != null)
			return vo.isStatus();
		return false;
	}

	private static boolean existsAdapterGroup(String adapterGroupName) {
		AdapterManager manager = AdapterManager.getInstance();
		AdapterGroupVO gvo = manager.getAdapterGroupVO(adapterGroupName);
		if (gvo != null)
			return true;
		return false;
	}

	private static String getDateTime(long time) {
		Instant instant = Instant.ofEpochMilli(time);
		ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
		return dateFormat.format(zdt);
	}
}
