package sfs.cluster.lobby.handlers.internal;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.logging.Logger;

import org.json.JSONObject;

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

import it.gotoandplay.smartfoxserver.SmartFoxServer;
import it.gotoandplay.smartfoxserver.data.User;
import it.gotoandplay.smartfoxserver.events.InternalEventObject;
import it.gotoandplay.smartfoxserver.extensions.AbstractExtension;
import it.gotoandplay.smartfoxserver.extensions.ExtensionHelper;

/**
 * Handles a user logging out of the Lobby
 */
public class LogoutHandler implements InternalHandler
{
	ClusterLobbyExtension parentExtension;
	Logger log;
	
	public LogoutHandler(AbstractExtension parentExtension)
    {
	    this.parentExtension = (ClusterLobbyExtension) parentExtension;
	    log = SmartFoxServer.log;
    }
	
	// Handle event
	public void handleInternalEvent(InternalEventObject ieo) throws Exception
	{
	    User user = (User) ieo.getObject("user");
	    
	    log.info("User: " + user.getName() + " was lost.");
	    parentExtension.removeUser(user.getName());
	    
	    // Update user count for this node
    	parentExtension.decrementUserCount();
	    
	    // Send notification to the users who have this mate in their friend list
	    sendFriendListUpdate(user.getName());
	}
	
	
	/*
	 * Update the friend list
	 */
	private void sendFriendListUpdate(String name)
	{
		// parameters
    	Map params = new HashMap();
    	params.put("_cmd", "fListUpdate");
		params.put("friend", name);
		params.put("status", "0");
    	
    	// Send friend list update
    	Map<String, LinkedList<Object>> updates = parentExtension.getFriendListManager().getClientsToUpdate(name);

    	// Local update
    	LinkedList localUsersToUpdate = updates.remove(parentExtension.getNodeId());
		
    	if (localUsersToUpdate != null)
    	{
    		JSONObject jso = new JSONObject(params);
    		parentExtension.sendResponse(jso, -1, null, localUsersToUpdate);
    	}
    	
    	// Remote update
    	for (Map.Entry<String, LinkedList<Object>> entry : updates.entrySet())
    	{
    		LinkedList<Object> nameList = entry.getValue();
    		String nodeName = entry.getKey();

    		if (nameList != null)
    		{
    			ClusterEvent event = new ClusterEvent( ClusterEvent.ON_FRIEND_LIST_UPDATE );
    			event.getParams().put("recipients", nameList);
    			event.getParams().put("jso", params);

    			DataStore.instance().dispatchClusterEvent(event, nodeName);
    		}
    	}
	}
}
