package com.eactive.eai.util;

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.server.EAIServerManager;
import com.eactive.eai.common.util.Logger;

import java.util.HashMap;
import java.util.Timer;

// Server Ping Test Health Check
public class HealthCheckManager implements Lifecycle {
	private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);

	private static HealthCheckManager manager = new HealthCheckManager();

	private LifecycleSupport lifecycle = new LifecycleSupport(this);

	private boolean started;

	private HashMap<String, Integer> serverHealthMap;

	private HealthCheckRunner runner;
	private Timer timer;

	public static HealthCheckManager getInstance() {
		return manager;
	}

	public void start() throws LifecycleException {
		if (started)
			throw new LifecycleException("RECEAICHC001");
		lifecycle.fireLifecycleEvent(STARTING_EVENT, this);
		this.serverHealthMap = new HashMap<String, Integer>();
		EAIServerManager mgr = EAIServerManager.getInstance();
		this.serverHealthMap.put(mgr.getLocalServerName(), 0);

		long period = 1000 * 5;
//        try {
//            period = Long.parseLong(pmanager.getProperty(PROP_GROUP, PROP_PERIOD));
//        } catch(Exception e) {}

		this.runner = new HealthCheckRunner();
		this.runner.setHealthCheckManager(this);

		this.timer = new Timer("HeadthCheckerTimer");
		this.timer.schedule(this.runner, period, period);

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

	public void stop() throws LifecycleException {
		if (!started)
			throw new LifecycleException("RECEAICHC002");
		logger.warn("Stopping");
		lifecycle.fireLifecycleEvent(STOPING_EVENT, this);

		
		this.timer.cancel();
		
		this.timer = null;
		this.runner = null;
		
		if(this.serverHealthMap != null) {
			this.serverHealthMap.clear();
			this.serverHealthMap = null;
		}
		
		started = false;
		lifecycle.fireLifecycleEvent(STOPPED_EVENT, null);
		logger.warn("Stopped");
	}

	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 void addFailCount(String instId, int count) {
		if(!started) return;
		Integer failCount = this.serverHealthMap.get(instId);

		if (failCount == null) {
			this.serverHealthMap.put(instId, count);
		} else {
			int newCount = 0;
			if (count > 0)
				newCount = failCount + count;
			this.serverHealthMap.put(instId, newCount);
		}
		logger.info("HealthCheckManager] Server Health : " + instId + " - " + this.serverHealthMap.get(instId));
	}

	public boolean getServerStatus(String instId) {
		if(!started) return false;
		Integer failCount = this.serverHealthMap.get(instId);
		if (failCount == null) {
			return false;
		} else {
			if (failCount >= 2)
				return false;
			else
				return true;
		}
	}
}
