package sfs.cluster.lobby.monitor;

import it.gotoandplay.smartfoxserver.data.User;
import it.gotoandplay.smartfoxserver.events.InternalEventObject;
import it.gotoandplay.smartfoxserver.extensions.AbstractExtension;
import it.gotoandplay.smartfoxserver.lib.ActionscriptObject;

import java.net.InetAddress;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import sfs.cluster.lobby.ClusterEventHandler;
import sfs.cluster.lobby.DataStore;
import sfs.cluster.lobby.data.ClusterEvent;

/**
 *  ** NOT USED IN THIS APPLICATION **
 *  You can ignore this class
 */
public class ClusterMonitorExtension extends AbstractExtension
{
	static final long TIMER_INTERVAL = 2000;
	static final int REQUIRED_PING_RESPONSE = 3; // milliseconds
	static final int WORKER_COUNT = 3;
	
	Thread monitorThread;
	boolean monitorRunning = true;
	
	LinkedBlockingQueue<ClusterEvent> mailBox;
	Executor threadPool;
	ClusterEventHandler clusterEventHandler;
	
	public ClusterMonitorExtension()
    {
		//
    }
	
	@Override
	public void init()
	{
		showSignature();
		
		// This is not registered in the cluster
		mailBox = new LinkedBlockingQueue<ClusterEvent>();
		
		// cluster event handler
		clusterEventHandler = new ClusterEventHandler(this, mailBox);
		
		//monitorThread = new Thread(this, "::monitorThread::");
		monitorThread.start();
		
		threadPool = Executors.newFixedThreadPool( WORKER_COUNT );
        for (int i = 0; i < WORKER_COUNT; i++)
        	threadPool.execute( clusterEventHandler );
		
		System.out.println("Monitor running...");
	}
	
	@Override
	public void destroy()
	{
		//
	}
	
	private void showSignature()
	{
		System.out.println(":::::::::::::::::::::::::::::::::");
		System.out.println(": SFS Cluster Monitor           :");
		System.out.println(": Prototype 1.0.0               :");
		System.out.println(":::::::::::::::::::::::::::::::::\n");
	}
	
	
	public void run()
	{
		monitorRunning = true;
		
		try
		{
			while (monitorRunning)
			{
				monitorTheCluster();
				Thread.sleep(TIMER_INTERVAL);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void monitorTheCluster() throws Exception
	{
		Set<String> availableNodes = DataStore.instance().nodeUserCounts.keySet();
		
		for (String nodeName : availableNodes)
		{
			// Check if cluster node is UP
			String ipAdr = nodeName.substring(0, nodeName.indexOf(':'));
			InetAddress clusterNode = InetAddress.getByName(ipAdr);
			
			//if (clusterNode != )
		}
	}

	
	
	public void handleRequest(String arg0, String[] arg1, User arg2, int arg3)
	{
	}
	
	public void handleRequest(String arg0, ActionscriptObject arg1, User arg2,  int arg3)
	{
	}
	
	public void handleInternalEvent(InternalEventObject arg0)
	{
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		ClusterMonitorExtension cme = new ClusterMonitorExtension();
		cme.init();
	}

}
