package com.eactive.eai.common.usedate;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
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 UseDateControlManager implements Lifecycle, Pass {
	static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

	@Autowired
	private UseDateControlDAO useDateControlDAO;

	private Map<String, UseDateControlVO> interfaceList;
	private boolean started;
	private LifecycleSupport lifecycle = new LifecycleSupport(this);

	private UseDateControlManager() {
		interfaceList = new HashMap<String, UseDateControlVO>();
	}

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

//    public static com.eactive.eai.common.usedate.Pass getPass() {
//        if(manager == null) {
//            synchronized(UseDateControlManager.class) {
//                if(manager == null) {
//                    manager = new UseDateControlManager();   
//                }   
//            }
//        }
//        
//        return manager;
//    }

	@Override
	public boolean isPass(String inter, long date) {
		UseDateControlVO vo = interfaceList.get(inter);
		if (vo == null) {
			return true;
		}
		return vo.isPass(date);
	}

	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 Exception {
		interfaceList = new HashMap<>();
		List<UseDateControlVO> list = useDateControlDAO.getUseDateContorlList();
		list.forEach(vo -> interfaceList.put(vo.getName(), vo));
	}

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

	public synchronized void reload(String inter) throws Exception {
		if (logger.isWarn()) {
			logger.warn("UseDateControlManager] reload Started ...");
		}
		UseDateControlVO vo = useDateControlDAO.getUseDateContorlListByInterface(inter);

		if (vo.isActivate()) {
			interfaceList.put(vo.getName(), vo);
		} else {
			interfaceList.remove(vo.getName());
		}

		if (logger.isWarn()) {
			logger.warn("UseDateControlManager] reload finished ...");
		}
	}

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

		lifecycle.fireLifecycleEvent(STOPING_EVENT, this);

		interfaceList.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 String[] getAllKeys() {
		Iterator it = this.interfaceList.keySet().iterator();
		String[] svcCd = new String[this.interfaceList.size()];
		for (int i = 0; it.hasNext(); i++) {
			svcCd[i] = (String) it.next();
		}
		Arrays.sort(svcCd);
		return svcCd;
	}

	public UseDateControlVO get(String inter) {
		return interfaceList.get(inter);
	}

	public void remove(String inter) {
		interfaceList.remove(inter);
	}

}
