package com.eactive.eai.common.submessage;

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

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 SubMessageManager implements Lifecycle {
	static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

	@Autowired
	SubMessageDAO subMessageDAO;

	private ConcurrentHashMap<String, HashMap<String, String>> headers = new ConcurrentHashMap<>();
	

	private boolean started;
	private LifecycleSupport lifecycle = new LifecycleSupport(this);

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

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

		lifecycle.fireLifecycleEvent(STARTING_EVENT, this);
		try {
			if (logger.isDebug()) {
				logger.warn("SubMessageManager] reload all Started ...");
			}
			init();
		} catch (Exception e) {
			throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICKE202"));
		}
		started = true;
		lifecycle.fireLifecycleEvent(STARTED_EVENT, this);
	}

	private void init() throws Exception {
		HashMap<String, HashMap<String, String>> map = (HashMap<String, HashMap<String, String>>) subMessageDAO.getAllSubMessages();
		headers = new ConcurrentHashMap<> (map);
	}

	public synchronized void reload() throws Exception {
		if (logger.isWarn()) {
			logger.warn("SubMessageManager] reload all Started ...");
		}
		init();
		if (logger.isWarn()) {
			logger.warn("SubMessageManager] reload all finished ...");
		}
	}
	
	public synchronized void remove(String bwkSvcKey) {
		this.headers.remove(bwkSvcKey);		
	}
	
	public synchronized void reload(String keyName) throws Exception {
		HashMap<String, String> map = (HashMap<String, String>) subMessageDAO.getSubMessage(keyName);
		if (map != null) {
			headers.put(keyName, map);			
		} else {
			throw new Exception("SubMessage not found in Database : key[" + keyName + "]");
		}
	}

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

		lifecycle.fireLifecycleEvent(STOPING_EVENT, this);

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

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

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

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

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

	public Map<String, String> getSubMessageMap(String bwkSvcKey) {
		return headers.get(bwkSvcKey);		
	}

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