package com.eactive.eai.common.c2rservice;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.eactive.eai.common.dao.DAOException;
import com.eactive.eai.common.exception.ExceptionUtil;
import com.eactive.eai.common.lifecycle.Lifecycle;
import com.eactive.eai.common.lifecycle.LifecycleException;
import com.eactive.eai.common.lifecycle.LifecycleListener;
import com.eactive.eai.common.lifecycle.LifecycleSupport;
import com.eactive.eai.common.util.ApplicationContextProvider;
import com.eactive.eai.common.util.Logger;
import com.eactive.eai.common.util.ObjectUtil;

@Component
public class C2RServiceManager implements Lifecycle {
	static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

	@Autowired
	C2RServiceDAO c2rServiceDAO;

	private Map<String, C2RServiceVO> c2rsMsgs = new HashMap<>();
	private boolean started;
	private LifecycleSupport lifecycle = new LifecycleSupport(this);

	public static synchronized C2RServiceManager getInstance() {
		return ApplicationContextProvider.getContext().getBean(C2RServiceManager.class);
	}

	public void start() throws LifecycleException {
		if (started)
			throw new LifecycleException("RECEAICMM201");

		lifecycle.fireLifecycleEvent(STARTING_EVENT, this);

		try {
			init();
		} catch (Exception e) {
			throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICMM202"));
		}

		started = true;
		lifecycle.fireLifecycleEvent(STARTED_EVENT, this);
	}

	private void init() throws DAOException {
		c2rsMsgs = null;
		c2rsMsgs = c2rServiceDAO.getAllC2RServices();
	}

	public synchronized void reload() throws Exception {
		if (logger.isWarn()) {
			logger.warn("C2RExtractManager] reload all Started ...");
		}
		init();
		if (logger.isWarn()) {
			logger.warn("C2RExtractManager] reload all finished ...");
		}
	}

	public synchronized void reload(String c2rExtnlInstiCd) throws Exception {
		if (logger.isWarn()) {
			logger.warn("C2RExtractManager] reload Started ...");
		}
		Map<String, C2RServiceVO> map = c2rServiceDAO.getC2RService(c2rExtnlInstiCd);
		if (map != null) {
			Iterator<String> it = map.keySet().iterator();
			String key = "";

			while (it.hasNext()) {
				key = it.next();
				C2RServiceVO vo = map.get(key);
				if ("1".equals(vo.getUseYn())) {
					c2rsMsgs.put(key, map.get(key));
				} else {
					c2rsMsgs.remove(key);
					logger.warn("C2RServiceManager] reload key[" + key + "] useYn[0] removed");
				}
			}
		}
		if (logger.isWarn()) {
			logger.warn("C2RExtractManager] reload finished ...");
		}
	}

	public void stop() throws LifecycleException {
		if (!started)
			throw new LifecycleException("RECEAICMM203");

		lifecycle.fireLifecycleEvent(STOPING_EVENT, this);

		c2rsMsgs.clear();

		started = false;
		lifecycle.fireLifecycleEvent(STOPPED_EVENT, this);
	}

	public void addLifecycleListener(LifecycleListener listener) {
		lifecycle.addLifecycleListener(listener);
	}

	public LifecycleListener[] findLifecycleListeners() {
		return lifecycle.findLifecycleListeners();
	}

	public void removeLifecycleListener(LifecycleListener listener) {
		lifecycle.removeLifecycleListener(listener);
	}

	public boolean isStarted() {
		return this.started;
	}

	public C2RServiceVO getC2RServiceVO(String c2rExtnlInstiCd, int svcPssSeq) {
		String key = c2rExtnlInstiCd + svcPssSeq;
		return getC2RServiceVO(key);
	}

	public C2RServiceVO getC2RServiceVO(String key) {
		C2RServiceVO aMsg = c2rsMsgs.get(key);
		if (aMsg != null) {
			try {
				return (C2RServiceVO) ObjectUtil.deepCopy(aMsg);
			} catch (Exception e) {
				if (logger.isError())
					logger.error(e.getMessage(), e);
				throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICMM204"));
			}
		} else {
			return aMsg;
		}
	}

	public String[] getAllKeys() {
		Iterator<String> it = this.c2rsMsgs.keySet().iterator();
		String[] svcCd = new String[this.c2rsMsgs.size()];

		for (int i = 0; it.hasNext(); i++) {
			svcCd[i] = it.next();
		}
		Arrays.sort(svcCd);
		return svcCd;
	}

	public void setC2RServiceVO(String code, C2RServiceVO vo) {
		c2rsMsgs.put(code, vo);
	}

	// db update 필요
	public void updateC2RServiceVO(String c2rExtnlInstiCd, int svcPssSeq, C2RServiceVO vo) {
		String key = c2rExtnlInstiCd + svcPssSeq;
		c2rsMsgs.put(key, vo);
	}

	public void removeC2RServiceVO(String c2rExtnlInstiCd, int svcPssSeq, C2RServiceVO vo) {
		String key = c2rExtnlInstiCd + svcPssSeq;
		c2rsMsgs.remove(key);
	}

	public void removeC2RServiceVO(String key) {
		c2rsMsgs.remove(key);
	}
}
