/*******************************************************************************
 * Copyright (c) 2006, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.debug.internal.ui.views.variables.details;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringTokenizer;

import org.eclipse.core.expressions.EvaluationResult;
import org.eclipse.core.expressions.Expression;
import org.eclipse.core.expressions.ExpressionConverter;
import org.eclipse.core.expressions.ExpressionTagNames;
import org.eclipse.core.expressions.IEvaluationContext;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.debug.internal.core.IConfigurationElementConstants;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IDetailPane;
import org.eclipse.debug.ui.IDetailPaneFactory;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.osgi.service.prefs.BackingStoreException;

/**
 * Organizes the detail factories contributed through the extension point and keeps
 * track of the detail panes the factories produce.  Accessed as a singleton through
 * the <code>getDefault()</code> method.
 *
 * @see IDetailPaneFactory
 * @see IDetailPane
 * @since 3.3
 */
public class DetailPaneManager {

	/**
	 * Acts as a proxy between the detail pane manager and the factories contributed
	 * to the extension point.  Only loads information from the plug-in xml and only
	 * instantiates the specified factory if required (lazy loading).
	 */
	private class DetailPaneFactoryExtension implements IDetailPaneFactory{

		private IConfigurationElement fConfigElement;
		private IDetailPaneFactory fFactory;
		private Expression fEnablementExpression;

		public DetailPaneFactoryExtension(IConfigurationElement configElement){
			fConfigElement = configElement;
		}

		/**
		 * Instantiates the factory and asks it to produce the IDetailPane for
		 * the given ID
		 * @param paneID the identifier of the detail pane to create
		 * @return the new detail pane or <code>null</code> if the backing {@link IDetailPaneFactory} is <code>null</code>
		 */
		@Override
		public IDetailPane createDetailPane(String paneID){
			if (getFactory() != null){
				return getFactory().createDetailPane(paneID);
			}
			return null;
		}

		/**
		 * Instantiates the factory and asks it for the set of detail pane
		 * IDs that the factory can produce for the given selection.
		 * @param selection the current view selection
		 * @return the set of detail pane type for the given selection or an empty set, never <code>null</code>
		 */
		@Override
		public Set<String> getDetailPaneTypes(IStructuredSelection selection) {
			if (getFactory() != null){
				return getFactory().getDetailPaneTypes(selection);
			}
			return Collections.EMPTY_SET;
		}

		/**
		 * Instantiates the factory and asks it for the detail pane ID
		 * that the factory considers the default for the given selection.
		 * @param selection the current view selection
		 * @return the identifier of the default detail pane or <code>null</code> if the backing {@link IDetailPaneFactory} is <code>null</code>
		 */
		@Override
		public String getDefaultDetailPane(IStructuredSelection selection) {
			if (getFactory() != null){
				return getFactory().getDefaultDetailPane(selection);
			}
			return null;
		}

		/**
		 * Instantiates the factory and asks it to produce the name of the detail pane
		 * for the given ID.
		 * @param paneID the detail pane identifier
		 * @return the name of the detail pane or <code>null</code> if the backing {@link IDetailPaneFactory} is <code>null</code>
		 */
		@Override
		public String getDetailPaneName(String paneID) {
			if (getFactory() != null){
				return getFactory().getDetailPaneName(paneID);
			}
			return null;
		}

		/**
		 * Instantiates the factory and asks it to produce the description of the
		 * detail pane for the given ID.
		 * @param paneID the detail pane identifier
		 * @return the description of the detail pane or <code>null</code> if the backing {@link IDetailPaneFactory} is <code>null</code>
		 */
		@Override
		public String getDetailPaneDescription(String paneID) {
			if (getFactory() != null){
				return getFactory().getDetailPaneDescription(paneID);
			}
			return null;
		}

		/**
		 * Returns the instantiated factory specified by the class property.
		 * @return the singleton {@link IDetailPaneFactory}
		 */
		private IDetailPaneFactory getFactory(){
			if (fFactory != null) {
				return fFactory;
			}
			try{
				Object obj = fConfigElement.createExecutableExtension(IConfigurationElementConstants.CLASS);
				if(obj instanceof IDetailPaneFactory) {
					fFactory = (IDetailPaneFactory)obj;
				} else {
					throw new CoreException(new Status(IStatus.ERROR, DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.INTERNAL_ERROR, "org.eclipse.debug.ui.detailFactories extension failed to load a detail factory because the specified class does not implement org.eclipse.debug.ui.IDetailPaneFactory.  Class specified was: " + obj, null)); //$NON-NLS-1$
				}
			} catch (CoreException e){
				DebugUIPlugin.log(e.getStatus());
				fFactory = null;
			}
			return fFactory;
		}

		/**
		 * Checks if the enablement expression for the factory evaluates to true for the
		 * given selection.
		 * @param selection the current view selection
		 * @return <code>true</code> if the backing {@link IDetailPaneFactory} applies to the given selection, <code>false</code> otherwise
		 */
		public boolean isEnabled(IStructuredSelection selection) {
			boolean enabled = false;
			// Only the default factory should be enabled for null selections
			if (selection == null || selection.isEmpty()){
				return "org.eclipse.debug.ui.defaultDetailPaneFactory".equals(fConfigElement.getAttribute(IConfigurationElementConstants.ID)); //$NON-NLS-1$
			}
			Expression expression = getEnablementExpression();
			if (expression != null) {
				List<?> list = selection.toList();
				IEvaluationContext context = DebugUIPlugin.createEvaluationContext(list);
				context.addVariable("selection", list); //$NON-NLS-1$
				enabled = evalEnablementExpression(context, expression);
			} else {
				enabled = true;
			}
			return enabled;
		}

		/**
		 * Evaluate the given expression within the given context and return
		 * the result. Returns <code>true</code> iff result is either TRUE or NOT_LOADED.
		 * This allows optimistic inclusion of shortcuts before plug-ins are loaded.
		 * Returns <code>false</code> if expression is <code>null</code>.
		 *
		 * @param exp the enablement expression to evaluate or <code>null</code>
		 * @param context the context of the evaluation. Usually, the
		 *  user's selection.
		 * @return the result of evaluating the expression
		 */
		private boolean evalEnablementExpression(IEvaluationContext context, Expression exp) {
			try{
				if (exp != null){
					EvaluationResult result = exp.evaluate(context);
					if (result == EvaluationResult.TRUE || result == EvaluationResult.NOT_LOADED){
						return true;
					}
				}
			} catch (CoreException e){
				DebugUIPlugin.log(e.getStatus());
			}
			return false;
		}

		/**
		 * Returns an expression that represents the enablement logic for the
		 * detail pane factory or <code>null</code> if none.
		 *
		 * @return an evaluatable expression or <code>null</code>
		 */
		private Expression getEnablementExpression(){
			// all of this stuff is optional, so...tedious testing is required
			if (fEnablementExpression == null) {
				try{
					IConfigurationElement[] elements = fConfigElement.getChildren(ExpressionTagNames.ENABLEMENT);
					IConfigurationElement enablement = elements.length > 0 ? elements[0] : null;
					if (enablement != null) {
						fEnablementExpression = ExpressionConverter.getDefault().perform(enablement);
					}
				} catch (CoreException e){
					DebugUIPlugin.log(e.getStatus());
					fEnablementExpression = null;
				}
			}
			return fEnablementExpression;
		}

	}

	/**
	 * There should only ever be once instance of this manager for the workbench.
	 */
	private static DetailPaneManager fgSingleton;

	/**
	 * Maps the IDs of types of detail panes to the factory that can create them.
	 * There can currently only be one factory for a given type of details pane.
	 */
	private Map<String, IDetailPaneFactory> fFactoriesByPaneID;

	/**
	 * Maps a Set of detail pane id's to the one detail pane id that is preferred.
	 */
	private Map<Set<String>, String> fPreferredDetailPanes;

	/**
	 * The set of all factories that have been loaded from the extension point.
	 */
	private List<DetailPaneFactoryExtension> fKnownFactories;

    /**
     * Preference key for storing the preferred detail panes map.
     * @see #storePreferredDetailsAreas()
     * @see #loadPreferredDetailsAreas()
     */
    public static final String PREF_DETAIL_AREAS = "preferredDetailPanes"; //$NON-NLS-1$

	private DetailPaneManager(){
		fFactoriesByPaneID = new HashMap<>();
		fFactoriesByPaneID.put(MessageDetailPane.ID, new DefaultDetailPaneFactory());
	}

	public static DetailPaneManager getDefault(){
		if (fgSingleton == null) {
			fgSingleton = new DetailPaneManager();
		}
		return fgSingleton;
	}

	/**
	 * Returns the ID of the preferred detail pane for the given selection.
	 *
	 * @param selection The selection to display in the detail pane
	 * @return The ID of the preferred detail pane or null
	 */
	public String getPreferredPaneFromSelection(IStructuredSelection selection){
		List<IDetailPaneFactory> possibleFactories = getEnabledFactories(selection);
		Set<String> possiblePaneIDs = getPossiblePaneIDs(possibleFactories, selection);
		return chooseDetailsAreaIDInSet(possiblePaneIDs, possibleFactories, selection);
	}

	/**
	 * Returns the set of all possible detail panes the can display the given
	 * selection.
	 *
	 * @param selection The selection to display in the detail pane
	 * @return The set of IDs of all possible detail panes for the given selection
	 */
	public Set<String> getAvailablePaneIDs(IStructuredSelection selection) {
		List<IDetailPaneFactory> possibleFactories = getEnabledFactories(selection);
		return getPossiblePaneIDs(possibleFactories, selection);
	}

	/**
	 * Given the ID of a details pane, this method will try to find the factory
	 * that creates it and return an instantiation of that area.
	 * <p>
	 * This method will not call the init() method of the IDetailsPane.
	 * </p>
	 *
	 * @param ID The ID of the requested pane
	 * @return The instantiated pane or null
	 */
	public IDetailPane getDetailPaneFromID(String ID){
		IDetailPaneFactory factory = fFactoriesByPaneID.get(ID);
		if (factory != null){
			return factory.createDetailPane(ID);
		}
		return null;
	}

	/**
	 * Given the ID of a details pane, this method will try to find the factory
	 * that creates it and ask it for the name of the details pane.
	 *
	 * @param ID The ID of the requested pane
	 * @return The name of the details pane or null
	 */
	public String getNameFromID(String ID){
		IDetailPaneFactory factory = fFactoriesByPaneID.get(ID);
		if (factory != null){
			return factory.getDetailPaneName(ID);
		}
		return null;
	}

	/**
	 * Given the ID of a details pane, this method will try to find the factory
	 * that creates it and ask it for the description of the details pane.
	 *
	 * @param ID The ID of the requested pane
	 * @return The description of the details pane or null
	 */
	public String getDescriptionFromID(String ID){
		IDetailPaneFactory factory = fFactoriesByPaneID.get(ID);
		if (factory != null){
			return factory.getDetailPaneDescription(ID);
		}
		return null;
	}


	/**
	 * Returns the set of IDetailPaneFactories (they will be DetailPaneFactoryDelegates) that were
	 * contributed to the extension point and are enabled for the given selection
	 * (enabled if the factory does not have an enablement expression or if the
	 * enablement expression evaluates to true).
	 * @param selection  the current view selection
	 *
	 * @return The factories enabled for the selection or an empty collection.
	 */
	private List<IDetailPaneFactory> getEnabledFactories(IStructuredSelection selection) {
		List<IDetailPaneFactory> factoriesForSelection = new ArrayList<>();
		if (fKnownFactories == null) {
			initializeDetailFactories();
		}
		for (IDetailPaneFactory currentFactory : fKnownFactories) {
			if (currentFactory instanceof DetailPaneFactoryExtension){
				if (((DetailPaneFactoryExtension)currentFactory).isEnabled(selection)){
					factoriesForSelection.add(currentFactory);
				}
			}
		}
		return factoriesForSelection;
	}

	/**
	 * Produces the set of IDs for all possible detail panes that can be used to display
	 * the given selection.
	 *
	 * @param factoriesToQuery The collection of factories to check
	 * @param selection The selection to be displayed
	 * @return Set of pane IDs or an empty set
	 */
	private Set<String> getPossiblePaneIDs(List<IDetailPaneFactory> factoriesToQuery, IStructuredSelection selection) {
		Set<String> idsForSelection = new LinkedHashSet<>();
		for (IDetailPaneFactory currentFactory : factoriesToQuery) {
			for (String currentAreaTypeID : currentFactory.getDetailPaneTypes(selection)) {
				fFactoriesByPaneID.put(currentAreaTypeID, currentFactory);
				idsForSelection.add(currentAreaTypeID);
			}
		}
		return idsForSelection;
	}

	/**
	 * Given a set of possible detail pane IDs, this method will determine which pane is
	 * preferred and should be used to display the selection.  This method chooses a pane
	 * by storing previous choices and can be set using a context menu.
	 *
	 * @param possiblePaneIDs The set of possible detail pane IDs
	 * @param enabledFactories the complete listing of enable {@link IDetailPaneFactory}s
	 * @param selection the current selection from the variables view
	 * @return The preferred detail pane ID or null
	 */
	private String chooseDetailsAreaIDInSet(Set<String> possiblePaneIDs, List<IDetailPaneFactory> enabledFactories, IStructuredSelection selection) {
		if (possiblePaneIDs == null || possiblePaneIDs.isEmpty()){
			return null;
		}

		String preferredID = getUserPreferredDetailPane(possiblePaneIDs);

		if (preferredID == null){
			// If there is no preferred pane already set, check the factories to see there is a default pane
			for (IDetailPaneFactory currentFactory : enabledFactories) {
				preferredID = currentFactory.getDefaultDetailPane(selection);
				if (preferredID != null) {
					break;
				}
			}
			// If the factories don't have a default, try to choose the DefaultDetailPane
			if (preferredID == null){
				Iterator<String> paneIterator = possiblePaneIDs.iterator();
				// If the DefaultDetailPane is not in the set, just use the first in the set
				preferredID = paneIterator.next();
				while (paneIterator.hasNext() && preferredID != DefaultDetailPaneFactory.DEFAULT_DETAIL_PANE_ID) {
					String currentID = paneIterator.next();
					if (currentID.equals(DefaultDetailPaneFactory.DEFAULT_DETAIL_PANE_ID)){
						preferredID = currentID;
					}
				}
			}
			setPreferredDetailPane(possiblePaneIDs, preferredID);
		}

		return preferredID;
	}

	/**
	 * Initializes the collection of known factories from extension point contributions.
	 */
	private synchronized void initializeDetailFactories(){
		if (fKnownFactories == null){
			fKnownFactories = new ArrayList<>();
			IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_DETAIL_FACTORIES);
			IConfigurationElement[] infos = extensionPoint.getConfigurationElements();
			DetailPaneFactoryExtension delegate = null;
			for(int i = 0; i < infos.length; i++) {
				delegate = new DetailPaneFactoryExtension(infos[i]);
				fKnownFactories.add(delegate);
			}
		}
	}

	/**
	 * Returns the preferred pane ID from the given set if the mapping has been set.
	 *
	 * @param possibleDetailsAreaIDs Set of possible pane IDs
	 * @return The preferred ID or null
	 */
	public String getUserPreferredDetailPane(Set<String> possibleDetailsAreaIDs) {
		if (fPreferredDetailPanes == null){
			loadPreferredDetailsAreas();
		}
		return fPreferredDetailPanes.get(possibleDetailsAreaIDs);

	}

	/**
	 * Adds or updates the mapping to set which pane ID is preferred for a certain
	 * set of possible IDs.
	 *
	 * @param possibleDetailsAreaIDs The set of possible IDs
	 * @param preferredDetailsAreaID The preferred ID in the set.
	 */
	public void setPreferredDetailPane(Set<String> possibleDetailsAreaIDs, String preferredDetailsAreaID) {
		if (possibleDetailsAreaIDs == null) {
			return;
		}
		if (fPreferredDetailPanes == null){
			loadPreferredDetailsAreas();
		}
		String currentKey = fPreferredDetailPanes.get(possibleDetailsAreaIDs);
		if (currentKey == null || !currentKey.equals(preferredDetailsAreaID)){
			fPreferredDetailPanes.put(possibleDetailsAreaIDs, preferredDetailsAreaID);
			storePreferredDetailsAreas();
		}

	}

    /**
     * Stores the map of preferred detail pane IDs to the preference store in the format:
     *
     * Key1A,Key1B:Value1|Key2A,Key2B,Key2C:Value2|
     *
     * Where the sub keys (Key1A, Key1B, etc.) are the elements of the set used at the
     * key in the mapping and the values are the associated String value in the mapping.
     */
    private void storePreferredDetailsAreas() {
        StringBuffer buffer= new StringBuffer();
		for (Entry<Set<String>, String> entry : fPreferredDetailPanes.entrySet()) {
			for (String currentID : entry.getKey()) {
				buffer.append(currentID);
				buffer.append(',');
			}
            buffer.deleteCharAt(buffer.length()-1);
            buffer.append(':');
            buffer.append(entry.getValue());
            buffer.append('|');
        }
        IEclipsePreferences node = InstanceScope.INSTANCE.getNode(DebugUIPlugin.getUniqueIdentifier());
        if(node != null) {
        	node.put(PREF_DETAIL_AREAS, buffer.toString());
        	try {
				node.flush();
			} catch (BackingStoreException e) {
				DebugUIPlugin.log(e);
			}
        }
    }

    /**
     * Loads the map of preferred detail pane IDs from the preference store.
     *
     * @see #storePreferredDetailsAreas()
     */
    private void loadPreferredDetailsAreas() {
		fPreferredDetailPanes = new HashMap<>();
    	String preferenceValue = Platform.getPreferencesService().getString(DebugUIPlugin.getUniqueIdentifier(),
    			PREF_DETAIL_AREAS,
    			"",  //$NON-NLS-1$
    			null);
    	StringTokenizer entryTokenizer = new StringTokenizer(preferenceValue,"|"); //$NON-NLS-1$
    	while (entryTokenizer.hasMoreTokens()){
    		String token = entryTokenizer.nextToken();
    		int valueStart = token.indexOf(':');
    		StringTokenizer keyTokenizer = new StringTokenizer(token.substring(0,valueStart),","); //$NON-NLS-1$
			Set<String> keys = new LinkedHashSet<>();
    		while (keyTokenizer.hasMoreTokens()){
    			keys.add(keyTokenizer.nextToken());
    		}
    		fPreferredDetailPanes.put(keys, token.substring(valueStart+1));
    	}
    }

}
