package org.eclipse.ui.views.markers.internal;

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

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
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.dynamichelpers.ExtensionTracker;
import org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler;
import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;

/**
 * The ProblemFilterRegistryReader is the registry reader for declarative
 * problem filters. See the org.eclipse.ui.markerSupport extension point.
 * 
 * @since 3.2
 * 
 */
public class MarkerSupportRegistry implements IExtensionChangeHandler {

	private static final String DESCRIPTION = "onDescription"; //$NON-NLS-1$

	private static final String ENABLED = "enabled"; //$NON-NLS-1$

	private static final Object ERROR = "ERROR";//$NON-NLS-1$

	static final String ID = "id"; //$NON-NLS-1$

	private static final Object INFO = "INFO";//$NON-NLS-1$

	private static final Object WARNING = "WARNING";//$NON-NLS-1$

	private static final String MARKER_ID = "markerId"; //$NON-NLS-1$

	/**
	 * The tag for the marker support extension
	 */
	public static final String MARKER_SUPPORT = "markerSupport";//$NON-NLS-1$

	private static final String NAME = "name"; //$NON-NLS-1$

	private static final Object ON_ANY = "ON_ANY"; //$NON-NLS-1$

	private static final Object ON_ANY_IN_SAME_CONTAINER = "ON_ANY_IN_SAME_CONTAINER";//$NON-NLS-1$

	private static final Object ON_SELECTED_AND_CHILDREN = "ON_SELECTED_AND_CHILDREN";//$NON-NLS-1$

	private static final Object ON_SELECTED_ONLY = "ON_SELECTED_ONLY"; //$NON-NLS-1$

	private static final Object PROBLEM_FILTER = "problemFilter";//$NON-NLS-1$

	private static final String SCOPE = "scope"; //$NON-NLS-1$

	private static final String SELECTED_TYPE = "selectedType"; //$NON-NLS-1$

	private static final String SEVERITY = "severity";//$NON-NLS-1$

	private static final String MARKER_TYPE_REFERENCE = "markerTypeReference"; //$NON-NLS-1$

	private static final Object MARKER_CATEGORY = "markerCategory";//$NON-NLS-1$

	private static final Object HIERARCHY = "hierarchy";//$NON-NLS-1$

	private static final String HIERARCHY_REFERENCE = "hierarchyReference";//$NON-NLS-1$

	private static final String TYPE = "type";//$NON-NLS-1$

	private static final String PATH = "PATH";//$NON-NLS-1$

	private static final String MESSAGE = "MESSAGE";//$NON-NLS-1$

	private static final String RESOURCE = "RESOURCE";//$NON-NLS-1$

	private static final String SEVERITY_HIERARCHY = "SEVERITY";//$NON-NLS-1$

	private static final String DIRECTION = "direction";//$NON-NLS-1$

	private static final String ASCENDING = "ASCENDING"; //$NON-NLS-1$

	private static final String ATTRIBUTE_MAPPING = "markerAttributeMapping"; //$NON-NLS-1$

	private static final Object MARKER_GROUPING = "markerGrouping"; //$NON-NLS-1$

	private static final String ATTRIBUTE = "attribute"; //$NON-NLS-1$

	private static final String VALUE = "value"; //$NON-NLS-1$

	private static MarkerSupportRegistry singleton;

	// Create a lock so that initiization happens in one thread
	private static Object creationLock = new Object();

	/**
	 * Get the instance of the registry.
	 * 
	 * @return ProblemFilterRegistry
	 */
	public static MarkerSupportRegistry getInstance() {
		if (singleton == null) {
			synchronized (creationLock) {
				if (singleton == null)// May have been created by blocking
					// thread
					singleton = new MarkerSupportRegistry();
			}
		}
		return singleton;
	}

	private Collection registeredFilters = new ArrayList();

	private Collection markerGroups = new ArrayList();

	private HashMap categories = new HashMap();

	private HashMap hierarchyOrders = new HashMap();

	private MarkerType rootType;

	/**
	 * Create a new instance of the receiver and read the registry.
	 */
	private MarkerSupportRegistry() {
		IExtensionTracker tracker = PlatformUI.getWorkbench()
				.getExtensionTracker();
		IExtensionPoint point = Platform.getExtensionRegistry()
				.getExtensionPoint(IDEWorkbenchPlugin.IDE_WORKBENCH,
						MARKER_SUPPORT);
		if (point == null)
			return;
		IExtension[] extensions = point.getExtensions();
		// initial population
		for (int i = 0; i < extensions.length; i++) {
			IExtension extension = extensions[i];
			processExtension(tracker, extension);
		}
		tracker.registerHandler(this, ExtensionTracker
				.createExtensionPointFilter(point));

	}

	/**
	 * Process the extension and register the result with the tracker.
	 * 
	 * @param tracker
	 * @param extension
	 */
	private void processExtension(IExtensionTracker tracker,
			IExtension extension) {
		IConfigurationElement[] elements = extension.getConfigurationElements();
		for (int j = 0; j < elements.length; j++) {
			IConfigurationElement element = elements[j];
			if (element.getName().equals(PROBLEM_FILTER)) {
				ProblemFilter filter = newFilter(element);
				registeredFilters.add(filter);
				tracker.registerObject(extension, filter,
						IExtensionTracker.REF_STRONG);

				continue;
			}
			if (element.getName().equals(MARKER_GROUPING)) {

				String[] markerTypes = getMarkerTypes(element);
				Map providers = getProviders(element);

				String name = element.getAttribute(NAME);
				String attribute = element.getAttribute(ATTRIBUTE);

				FieldMarkerGroup group = new FieldMarkerGroup(name, attribute, providers,
						markerTypes);

				markerGroups.add(group);
				tracker.registerObject(extension, group,
						IExtensionTracker.REF_STRONG);
			}

			if (element.getName().equals(MARKER_CATEGORY)) {

				String[] markerTypes = getMarkerTypes(element);
				String categoryName = element.getAttribute(NAME);

				for (int i = 0; i < markerTypes.length; i++) {
					categories.put(markerTypes[i], categoryName);

				}
				tracker.registerObject(extension, categoryName,
						IExtensionTracker.REF_STRONG);
			}

			if (element.getName().equals(HIERARCHY)) {

				String markerType = getMarkerTypes(element)[0];

				IConfigurationElement[] types = element
						.getChildren(HIERARCHY_REFERENCE);
				IField[] properties = new IField[types.length];
				int[] directions = new int[types.length];
				for (int i = 0; i < types.length; i++) {
					properties[i] = getFieldFor(types[i].getAttribute(TYPE));
					String direction = types[i].getAttribute(DIRECTION);
					if (direction == ASCENDING)
						directions[i] = TableSorter.ASCENDING;
					else
						directions[i] = TableSorter.DESCENDING;
				}

				int[] priorities = new int[properties.length];
				for (int i = 0; i < priorities.length; i++) {
					priorities[i] = i;
				}

				TableSorter sorter = new TableSorter(properties, priorities,
						directions);
				hierarchyOrders.put(markerType, sorter);
				tracker.registerObject(extension, sorter,
						IExtensionTracker.REF_STRONG);

			}
		}
	}

	/**
	 * Return the field that matches attribute
	 * 
	 * @param attribute
	 * @return IField or <code>null</code> if there is no matching field.
	 */
	private IField getFieldFor(String attribute) {
		if (attribute.equals(PATH))
			return new FieldFolder();
		if (attribute.equals(MESSAGE))
			return new FieldMessage();
		if (attribute.equals(SEVERITY_HIERARCHY))
			return new FieldSeverity();
		if (attribute.equals(RESOURCE))
			return new FieldResource();

		return null;

	}

	/**
	 * Get the markerTypes defined in element.
	 * 
	 * @param element
	 * @return String[]
	 */
	private String[] getMarkerTypes(IConfigurationElement element) {
		IConfigurationElement[] types = element
				.getChildren(MARKER_TYPE_REFERENCE);
		String[] ids = new String[types.length];
		for (int i = 0; i < ids.length; i++) {
			ids[i] = types[i].getAttribute(ID);
		}
		return ids;
	}

	/**
	 * Find the attributeMappings from element.
	 * 
	 * @param element
	 * @return Map
	 */
	private Map getProviders(final IConfigurationElement element) {

		IConfigurationElement[] mappings = element
				.getChildren(ATTRIBUTE_MAPPING);

		HashMap valuesToStrings = new HashMap();
		for (int i = 0; i < mappings.length; i++) {
			valuesToStrings.put(mappings[i].getAttribute(VALUE), mappings[i]
					.getAttribute(NAME));
		}

		return valuesToStrings;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#addExtension(org.eclipse.core.runtime.dynamichelpers.IExtensionTracker,
	 *      org.eclipse.core.runtime.IExtension)
	 */
	public void addExtension(IExtensionTracker tracker, IExtension extension) {
		processExtension(tracker, extension);
	}

	/**
	 * Get the collection of currently registered filters.
	 * 
	 * @return Collection of ProblemFilter
	 */
	public Collection getRegisteredFilters() {
		Collection filteredFilters = new ArrayList();
		Iterator registeredIterator = registeredFilters.iterator();
		while (registeredIterator.hasNext()) {
			ProblemFilter next = (ProblemFilter) registeredIterator.next();
			if (next.isFilteredOutByActivity())
				continue;
			filteredFilters.add(next);
		}

		return filteredFilters;
	}

	/**
	 * Get the constant for scope from element. Return -1 if there is no value.
	 * 
	 * @param element
	 * @return int one of MarkerView#ON_ANY MarkerView#ON_SELECTED_ONLY
	 *         MarkerView#ON_SELECTED_AND_CHILDREN
	 *         MarkerView#ON_ANY_IN_SAME_CONTAINER
	 */
	private int getScopeValue(IConfigurationElement element) {
		String scope = element.getAttribute(SCOPE);
		if (scope == null)
			return -1;
		if (scope.equals(ON_ANY))
			return MarkerFilter.ON_ANY;
		if (scope.equals(ON_SELECTED_ONLY))
			return MarkerFilter.ON_SELECTED_ONLY;
		if (scope.equals(ON_SELECTED_AND_CHILDREN))
			return MarkerFilter.ON_SELECTED_AND_CHILDREN;
		if (scope.equals(ON_ANY_IN_SAME_CONTAINER))
			return MarkerFilter.ON_ANY_IN_SAME_CONTAINER;

		return -1;
	}

	/**
	 * Get the constant for scope from element. Return -1 if there is no value.
	 * 
	 * @param element
	 * @return int one of MarkerView#ON_ANY MarkerView#ON_SELECTED_ONLY
	 *         MarkerView#ON_SELECTED_AND_CHILDREN
	 *         MarkerView#ON_ANY_IN_SAME_CONTAINER
	 */
	private int getSeverityValue(IConfigurationElement element) {
		String severity = element.getAttribute(SEVERITY);
		if (severity == null)
			return -1;
		if (severity.equals(INFO))
			return ProblemFilter.SEVERITY_INFO;
		if (severity.equals(WARNING))
			return ProblemFilter.SEVERITY_WARNING;
		if (severity.equals(ERROR))
			return ProblemFilter.SEVERITY_ERROR;

		return -1;
	}

	/**
	 * Read the problem filters in the receiver.
	 * 
	 * @param element
	 *            the filter element
	 * @return ProblemFilter
	 */
	private ProblemFilter newFilter(IConfigurationElement element) {
		ProblemFilter filter = new ProblemFilter(element.getAttribute(NAME));

		filter.createContributionFrom(element);

		String enabledValue = element.getAttribute(ENABLED);
		filter.setEnabled(enabledValue == null
				|| Boolean.valueOf(enabledValue).booleanValue());

		int scopeValue = getScopeValue(element);
		if (scopeValue >= 0) {
			filter.setOnResource(scopeValue);
		}

		String description = element.getAttribute(DESCRIPTION);
		if (description != null) {
			boolean contains = true;
			if (description.charAt(0) == '!') {// does not contain flag
				description = description.substring(1, description.length());
				contains = false;
			}
			filter.setContains(contains);
			filter.setDescription(description);
		}

		int severityValue = getSeverityValue(element);
		if (severityValue > 0) {
			filter.setSelectBySeverity(true);
			filter.setSeverity(severityValue);
		} else
			filter.setSelectBySeverity(false);

		List selectedTypes = new ArrayList();
		IConfigurationElement[] types = element.getChildren(SELECTED_TYPE);
		for (int j = 0; j < types.length; j++) {
			String markerId = types[j].getAttribute(MARKER_ID);
			if (markerId != null) {
				MarkerType type = filter.getMarkerType(markerId);
				if (type == null) {
					IStatus status = new Status(IStatus.WARNING,
							IDEWorkbenchPlugin.IDE_WORKBENCH, IStatus.WARNING,
							MarkerMessages.ProblemFilterRegistry_nullType, null);
					IDEWorkbenchPlugin.getDefault().getLog().log(status);
				} else
					selectedTypes.add(type);
			}
		}

		if (selectedTypes.size() > 0) // Only set the types if there are any
			// specified
			filter.setSelectedTypes(selectedTypes);

		return filter;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.dynamichelpers.IExtensionChangeHandler#removeExtension(org.eclipse.core.runtime.IExtension,
	 *      java.lang.Object[])
	 */
	public void removeExtension(IExtension extension, Object[] objects) {
		for (int i = 0; i < objects.length; i++) {
			if (objects[i] instanceof ProblemFilter)
				registeredFilters.remove(objects[i]);

			if (objects[i] instanceof FieldMarkerGroup) {
				markerGroups.remove(objects[i]);
			}

			if (objects[i] instanceof String) {
				removeValues(objects[i], categories);
			}

			if (objects[i] instanceof TableSorter) {
				removeValues(objects[i], hierarchyOrders);
			}

		}

	}

	/**
	 * Remove the value from all of the collection sets in cache. If the
	 * collection is empty remove the key as well.
	 * 
	 * @param value
	 * @param cache
	 */
	private void removeValues(Object value, HashMap cache) {
		Collection keysToRemove = new ArrayList();
		Iterator keys = cache.keySet().iterator();
		while (keys.hasNext()) {
			String key = (String) keys.next();
			Object next = cache.get(key);
			if (next instanceof Collection) {
				Collection collection = (Collection) next;
				if (collection.contains(value)) {
					collection.remove(value);
					if (collection.isEmpty())
						keysToRemove.add(key);
					break;
				}
			} else {
				if (cache.get(key).equals(value))
					keysToRemove.add(key);
			}
		}
		Iterator keysToRemoveIterator = keysToRemove.iterator();
		while (keysToRemoveIterator.hasNext()) {
			cache.remove(keysToRemoveIterator.next());
		}
	}

	/**
	 * Get the category associated with marker. Return <code>null</code> if
	 * there are none.
	 * 
	 * @param marker
	 * @return String or <code>null</code>
	 */
	public String getCategory(IMarker marker) {
		try {
			return getCategory(marker.getType());
		} catch (CoreException e) {
			Util.log(e);
		}
		return null;
	}

	/**
	 * Get the category associated with markerType. Return <code>null</code>
	 * if there are none.
	 * 
	 * @param markerType
	 * @return String or <code>null</code>
	 */
	public String getCategory(String markerType) {
		if (categories.containsKey(markerType))
			return (String) categories.get(markerType);
		return null;
	}

	/**
	 * Return the TableSorter that corresponds to type.
	 * 
	 * @param type
	 * @return TableSorter
	 */
	public TableSorter getSorterFor(String type) {
		if (hierarchyOrders.containsKey(type))
			return (TableSorter) hierarchyOrders.get(type);

		TableSorter sorter = findSorterInChildren(type, getRootType());
		if (sorter == null)
			return new TableSorter(new IField[0], new int[0], new int[0]);
		return sorter;
	}

	/**
	 * Return the list of root marker types.
	 * 
	 * @return List of MarkerType.
	 */
	private MarkerType getRootType() {
		if (rootType == null) {
			rootType = (MarkerTypesModel.getInstance())
					.getType(IMarker.PROBLEM);
		}
		return rootType;
	}

	/**
	 * Find the best match sorter for typeName in the children. If it cannot be
	 * found then return <code>null</code>.
	 * 
	 * @param typeName
	 * @param type
	 * @return TableSorter or <code>null</code>.
	 */
	private TableSorter findSorterInChildren(String typeName, MarkerType type) {

		MarkerType[] types = type.getAllSubTypes();
		TableSorter defaultSorter = null;
		if (hierarchyOrders.containsKey(type.getId()))
			defaultSorter = (TableSorter) hierarchyOrders.get(type.getId());

		for (int i = 0; i < types.length; i++) {
			MarkerType[] subtypes = types[i].getAllSubTypes();
			for (int j = 0; j < subtypes.length; j++) {
				TableSorter sorter = findSorterInChildren(typeName, subtypes[j]);
				if (sorter != null)
					return sorter;
			}
		}
		return defaultSorter;

	}

	/**
	 * Return the FieldMarkerGroups in the receiver.
	 * @return Collection of FieldMarkerGroup
	 */
	public Collection getMarkerGroups() {
		return markerGroups;
	}

}
