package org.eclipse.osbp.runtime.common.event;

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

import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.model.application.ui.MUIElement;
import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SelectionStore {
	/** The Constant log. */
	protected static final Logger log = LoggerFactory.getLogger(SelectionStore.class.getName());
	
	private Map<String, Object> selections = new HashMap<>();
	
	public void setSelection(String fqn, Object id) {
		log.debug("setSelection({},{})",fqn,id);
		if(id != null) {
			selections.put(fqn, id);
		} else {
			selections.remove(fqn);
		}
	}
	
	public Object getSelection(String fqn) {
		if(selections.containsKey(fqn)) {
			if( log.isDebugEnabled() ) log.debug("getSelection({}) = {}",fqn,selections.get(fqn));
			return selections.get(fqn);
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	private void addSelection(String fqn, Object id) {
		log.debug("addSelection({},{})",fqn,id);		
		if(!selections.containsKey(fqn) || !(selections.get(fqn) instanceof List<?>)) {
			log.debug("    as new ... ");
			selections.put(fqn, new ArrayList<>());
		}
		((List<Object>)selections.get(fqn)).add(id);
	}
	
	@SuppressWarnings("unchecked")
	private void removeSelection(String fqn, Object id) {
		if(selections.containsKey(fqn) && selections.get(fqn) instanceof List<?>) {
			((List<Object>)selections.get(fqn)).remove(id);
			if(((List<Object>)selections.get(fqn)).isEmpty()) {
				log.debug("removeSelection({},{})",fqn,id);
				selections.remove(fqn);
			}
		}
	}

	private static IEclipseContext getContext(MPart part) {
		MUIElement element = part;
		while(element != null && !(element instanceof MPerspective)) {
			element = element.getParent();
		}
		if(element != null) {
			if( log.isDebugEnabled() ) log.debug("getContext() returns {}",((MPerspective)element).getContext().toString());
			return ((MPerspective)element).getContext(); 
		}
		return null;
	}
	
	/**
	 * Adds a selection to perspective context.
	 *
	 * @param part the part
	 * @param fqn the fqn
	 * @param id the id
	 * @return true, if successful
	 */
	public static boolean addSelectionToPerspectiveContext(MPart part, String fqn, Object id) {
		IEclipseContext context = getContext(part);
		if(context != null) {
			if(context.get(SelectionStore.class) == null) {
				context.set(SelectionStore.class, new SelectionStore());
			}
			context.get(SelectionStore.class).addSelection(fqn, id);
			return true;
		}
		return false;
	}
	
	/**
	 * Removes a selection from perspective context.
	 *
	 * @param part the part
	 * @param fqn the fqn
	 * @param id the id
	 * @return true, if successful
	 */
	public static boolean removeSelectionFromPerspectiveContext(MPart part, String fqn, Object id) {
		IEclipseContext context = getContext(part);
		if(context != null) {
			if(context.get(SelectionStore.class) == null) {
				context.set(SelectionStore.class, new SelectionStore());
			}
			context.get(SelectionStore.class).removeSelection(fqn, id);
			return true;
		}
		return false;
	}

	/**
	 * Store a selection by id to perspective context.
	 *
	 * @param key the fully qualified name of the id field
	 * @param value the id object
	 * @return true, if successful
	 */
	public static boolean putSelectionToPerspectiveContext(MPart part, String key, Object value) {
		IEclipseContext context = getContext(part);
		if(context != null) {
			if(context.get(SelectionStore.class) == null) {
				context.set(SelectionStore.class, new SelectionStore());
			}
			context.get(SelectionStore.class).setSelection(key, value);
			return true;
		}
		return false;
	}
	
	/**
	 * Gets a selection by id from perspective context.
	 *
	 * @param key the fully qualified name of the id field
	 * @return the selected id object from perspective context
	 */
	public static Object getSelectionFromPerspectiveContext(MPart part, String key) {
		IEclipseContext context = getContext(part);
		if(context != null) {
			if(context.get(SelectionStore.class) != null) {
				return context.get(SelectionStore.class).getSelection(key);
			}
		}
		return null;
	}
}
