package com.eactive.eai.common.bizkey;

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.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;

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

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

	@Autowired
	private BizKeyDAO bizKeyDAO;

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

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

		lifecycle.fireLifecycleEvent(STARTING_EVENT, this);

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

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

	private void init() throws Exception {
		messages = null;
		messages = bizKeyDAO.getAllBizKeys();
	}

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

	public synchronized void reload(String eaiSvcCd, String exrClsNm) throws Exception {
		Map<String, BizKeyVO> map = bizKeyDAO.getBizKey(eaiSvcCd, exrClsNm);
		if (map != null) {
			Iterator<String> it = map.keySet().iterator();

			String key = "";
			while (it.hasNext()) {
				key = it.next();
				messages.put(key, map.get(key));
			}
		}
	}

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

		lifecycle.fireLifecycleEvent(STOPING_EVENT, this);

		messages.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 BizKeyVO getBizKey(String code) {
		return messages.get(code);
	}

	public BizKeyVO getBizKey(String eaiSvcCd, String exrClsNm) {
		return messages.get(eaiSvcCd + exrClsNm);
	}

	public void setBizKey(String code, BizKeyVO msg) {
		messages.put(code, msg);
	}

	public void setBizKey(String eaiSvcCd, String exrClsNm, BizKeyVO vo) {
		messages.put(eaiSvcCd + exrClsNm, vo);
	}

	public void updateBizKey(String eaiSvcCd, String exrClsNm, BizKeyVO vo) {
		messages.put(eaiSvcCd + exrClsNm, vo);
	}

	public void removeBizKey(String code) {
		messages.remove(code);
	}

	public String[] getAllKeyNames() {
		Iterator<String> it = this.messages.keySet().iterator();
		String[] name = new String[this.messages.size()];
		for (int i = 0; it.hasNext(); i++) {
			name[i] = it.next();
		}
		Arrays.sort(name);
		return name;
	}
}
