package org.iri_research.renkan.coweb.event;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.inject.Named;

import org.coweb.CowebException;
import org.iri_research.renkan.models.RenkanSessionModeratorState;
import org.iri_research.renkan.models.RosterUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@Named
public class RosterSyncEventManager implements ISyncEventManager<RosterUser, String> {

	private final Logger logger = LoggerFactory.getLogger(RosterSyncEventManager.class);
	

	@Override
	public void insert(String clientId, Map<String, Object> data) {
		logger.debug("RosterUserSyncEventManager.insert " + data.toString());
		
		@SuppressWarnings("unchecked")
		Map<String, Object> values = (Map<String, Object>) data.get("value");
		String projectId = (String) values.get("_project_id");

		List<RosterUser> usersList = null;
		
		if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
			usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
		}
		if(usersList == null) {
			usersList = new ArrayList<RosterUser>();
			RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().put(projectId, usersList);
		}
				
		String id = (String)values.get("id");

		RosterUser user = null;
		
		for (RosterUser rosterUser : usersList) {
			if(rosterUser.getId().equals(id)) {
				user = rosterUser;
				break;
			}
		}
		if(user != null) {
			this.update(clientId, data);
			return;
		}
		
		String title = (String)values.get("title");
		String description = (String)values.get("description");
		String uri = (String)values.get("uri");
		String color = (String)values.get("color");
		Long site_id = (Long)values.get("site_id");
		
		user = new RosterUser(id, title, description, uri, color, projectId, site_id, clientId);
		
		Integer position = (Integer)data.get("position");
		if(position == null) {
			position = new Integer(0);
		}
		
		usersList.add(position.intValue(), user);
		
		logger.debug("RosterUserSyncEventManager.insert in  " + projectId + " : " + RenkanSessionModeratorState.INSTANCE.getProjectsActivationMap().toString());
		
	}

	@Override
	public void nullOperation(String clientId, Map<String, Object> data) {
		// do nothing
		return;
	}

	@Override
	public void update(String clientId, Map<String, Object> data) {
		logger.debug("RosterUserSyncEventManager.update " + data.toString());

		@SuppressWarnings("unchecked")
		Map<String, Object> values = (Map<String, Object>) data.get("value");
		String projectId = (String) values.get("_project_id");

		List<RosterUser> usersList = null;
		
		if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
			usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
		}
		
		if(usersList == null) {
			logger.debug("RosterUserSyncEventManager.update : null user list");
			return;
		}
		
		String id = (String)values.get("id");

		RosterUser user = null;
		
		for (RosterUser rosterUser : usersList) {
			if(rosterUser.getId().equals(id)) {
				user = rosterUser;
				break;
			}
		}
		
		if(user == null) {
			logger.debug("RosterUserSyncEventManager.update : user not found in list");
			return;
		}
		
		String title = (String)values.get("title");
		String description = (String)values.get("description");
		String uri = (String)values.get("uri");
		String color = (String)values.get("color");
		
		if(title != null) {
			user.setTitle(title);
		}
		if(description != null) {
			user.setDescription(description);
		}
		if(uri != null) {
			user.setUri(uri);
		}
		if(color != null) {
			user.setColor(color);
		}
		
		return;
		
	}

	@Override
	public void delete(String clientId, Map<String, Object> data) {
		logger.debug("RosterUserSyncEventManager.delete " + data.toString());
		
		@SuppressWarnings("unchecked")
		Map<String, Object> values = (Map<String, Object>) data.get("value");
		String projectId = (String) values.get("_project_id");

		List<RosterUser> usersList = null;
		
		if(RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().containsKey(projectId)) {
			usersList = RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().get(projectId);
		}
		
		if(usersList == null) {
			logger.debug("RosterUserSyncEventManager.delete : null user list");
			return;
		}
		
		Integer position = (Integer)data.get("position");
		
		if(position == null || position < 0) {
			throw new CowebException("object delete: bad delete position", String.format("Bad position %s not found", position==null?"null":position.toString()));
		}
		int index = position.intValue();
		
		usersList.remove(index);
		
		if(usersList.isEmpty()) {
			RenkanSessionModeratorState.INSTANCE.getProjectsUsersList().remove(projectId);
		}
		
		return;
		
	}
	
	@Override
	public void dispatchEvent(String clientId, Map<String, Object> data) {
		
		String eventType = (String) data.get("type");
		
		if("null".equalsIgnoreCase(eventType)) {
			this.nullOperation(clientId, data);
		}
		else if ("update".equalsIgnoreCase(eventType)) {
			this.update(clientId, data);
		}
		else if ("insert".equalsIgnoreCase(eventType)) {
			this.insert(clientId, data);
		}
		else if("delete".equalsIgnoreCase(eventType)) {
			this.delete(clientId, data);
		}
		else {		
			logger.warn(String.format("dispatchEvent : eventType unknown %s", eventType));
		}
	}


}
