/*******************************************************************************
 * Copyright (c) 2001, 2011 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.wst.html.core.internal.validation;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.wst.html.core.internal.HTMLCorePlugin;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;

/**
 * This class must be called only by the validation framework.
 * 
 * This singleton interacts with the eclipse workbench's Task list.
 * TaskListUtility adds and removes tasks from the list.
 * 
 * This class must not be called outside of an IWorkspaceRunnable or
 * IRunnableWithProgress. Many resource deltas can be generated by the methods
 * in this class.
 * 
 * This came from TaskListUtility
 */
public class TaskListUtility {
	// private static final String PLUGIN_ID = ValidationPlugin.PLUGIN_ID;
	private static final String PLUGIN_ID = HTMLCorePlugin.ID;
	private static final String VALIDATION_MARKER = PLUGIN_ID + ".problemmarker"; //$NON-NLS-1$ // The extension which is used to add validation markers to the task list
	private static final String VALIDATION_MARKER_OWNER = "owner"; //$NON-NLS-1$ // The IValidator who owns the IMarker on the task list
	private static final String VALIDATION_MARKER_SEVERITY = "validationSeverity"; //$NON-NLS-1$ // one of the IMessage values
	private static final String VALIDATION_MARKER_TARGETOBJECT = "targetObject"; //$NON-NLS-1$ // When more than one target object resolves to the same IResource, this field identifies which targetObject owns a particular message.
	private static final String VALIDATION_MARKER_GROUP = "groupName"; //$NON-NLS-1$ // For incremental validation, this field associates a message with a group, so that a subset of messages may be removed from a file.
	private static final String VALIDATION_MARKER_MESSAGEID = "messageId"; //$NON-NLS-1$ // Persist the message id of the message, not just the translated text.
	private static final int DEPTH_INFINITE = IResource.DEPTH_INFINITE;
	private static final int DEPTH_ZERO = IResource.DEPTH_ZERO;
	private final static IMarker[] NO_MARKERS = new IMarker[0];

	/**
	 * This method adds a message to a resource in the task list.
	 */
	public static IMarker addTask(String pluginId, IResource resource, String location, String messageId, String message, int markerType, String targetObjectName, String groupName, int offset, int length) throws CoreException {
		if ((message == null) || (resource == null)) {
			return null;
		}

		int severity = getSeverity(markerType);

		// Allow duplicate entries in the task list.
		// Prior to a full validation, the validation framework will remove
		// all messages owned
		// by a validator before it is executed.
		// Prior to an incremental validation, the validation framework will
		// remove all messages,
		// on each of the changed resources, owned by a validator before it is
		// invoked.
		// 
		// It is up to the validator to make sure that it is not adding the
		// same message
		// in more than one place, and also to clear out any old messages
		// which are not cleared
		// by the validation framework.
		IMarker item = resource.createMarker(VALIDATION_MARKER); // add a
																	// validation
																	// marker

		// For performance reasons, replace the multiple setAttribute
		// calls above with a single setAttributes call.
		boolean offsetSet = ((offset != IMessage.OFFSET_UNSET) && (length != IMessage.OFFSET_UNSET));
		int size = (offsetSet) ? 10 : 8; // add CHAR_START, CHAR_END only
											// if the offset is set. If the
											// offset is set, it takes
											// precendence over the line
											// number. (eclipse's rule, not
											// mine.)
		String[] attribNames = new String[size];
		Object[] attribValues = new Object[size];

		// Very first thing, add the owner. That way, if the code dies
		// before things are persisted, hopefully this marker will be
		// persisted.
		// Hopefully, eclipse WILL persist this field, as requested.
		attribNames[0] = VALIDATION_MARKER_OWNER;
		attribValues[0] = pluginId;
		attribNames[1] = VALIDATION_MARKER_SEVERITY; // this validation
														// severity is stored,
														// in addition to the
														// marker severity, to
														// enable more than
														// one severity of
														// message to be
														// displayed. e.g.
														// ERROR | WARNING
														// (using binary OR).
														// The IMarker
														// constants are
														// regular decimal
														// constants.
		attribValues[1] = new Integer(markerType);
		attribNames[2] = VALIDATION_MARKER_TARGETOBJECT; // to distinguish
															// between
															// messages which
															// are registered
															// on an
															// IResource, but
															// against
															// different
															// target objects
		attribValues[2] = ((targetObjectName == null) ? "" : targetObjectName); //$NON-NLS-1$
		attribNames[3] = VALIDATION_MARKER_GROUP;
		attribValues[3] = ((groupName == null) ? "" : groupName); //$NON-NLS-1$
		attribNames[4] = IMarker.MESSAGE;
		attribValues[4] = message;
		attribNames[5] = VALIDATION_MARKER_MESSAGEID;
		attribValues[5] = messageId;

		attribNames[6] = IMarker.SEVERITY; // IMarker.SEVERITY_ERROR,
											// IMarker.SEVERITY_WARNING,
											// IMarker.SEVERITY_INFO
		attribValues[6] = new Integer(severity);
		try {
			// If the location is a line number, store it as a line number
			Integer lineNumber = Integer.valueOf(location);
			attribNames[7] = IMarker.LINE_NUMBER;
			attribValues[7] = lineNumber;
		}
		catch (NumberFormatException exc) {
			// Otherwise, store it as a text location
			attribNames[7] = IMarker.LOCATION;
			attribValues[7] = location;
		}

		if (offsetSet) {
			attribNames[8] = IMarker.CHAR_START;
			attribValues[8] = new Integer(offset);
			attribNames[9] = IMarker.CHAR_END;
			attribValues[9] = new Integer(offset + length);
		}

		item.setAttributes(attribNames, attribValues);

		return item;
	}

	/**
	 * Given one of the SeverityEnum severities, return the IMarker severity
	 * int that is its equivalent.
	 */
	private static int getSeverity(int severityEnumValue) {
		switch (severityEnumValue) {
			case (IMessage.HIGH_SEVERITY) : {
				return IMarker.SEVERITY_ERROR;
			}

			case (IMessage.LOW_SEVERITY) : {
				return IMarker.SEVERITY_INFO;
			}

			case (IMessage.NORMAL_SEVERITY) : {
				return IMarker.SEVERITY_WARNING;
			}

			case (IMessage.ALL_MESSAGES) :
			case (IMessage.ERROR_AND_WARNING) :
			default : {
				// assume it's a warning.
				return IMarker.SEVERITY_WARNING;
			}
		}
	}

	private static int getDepth(IResource resource) {
		if (resource instanceof IProject) {
			return DEPTH_INFINITE; // DEPTH_INFINITE means get this project's
									// markers, and the markers belonging to
									// the project's children.
		}
		else if (resource instanceof IWorkspaceRoot) {
			// Needed for the ValidationMigrator when it checks for orphan
			// tasks.
			return DEPTH_INFINITE; // DEPTH_INFINITE means get all of the
									// markers in the workspace
		}

		return DEPTH_ZERO; // DEPTH_ZERO means just this resource, not its
							// children
	}

	private static IMarker[] getValidationTasks(IResource resource, int severity, int depth) {
		IMarker[] tempMarkers = null;
		int validCount = 0;
		try {
			IMarker[] allMarkers = null;
			try {
				allMarkers = resource.findMarkers(VALIDATION_MARKER, false, depth); // false
																					// means
																					// only
																					// consider
																					// PROBLEM_MARKER,
																					// not
																					// variants
																					// of
																					// PROBLEM_MARKER.
																					// Since
																					// addTask
																					// only
																					// adds
																					// PROBLEM_MARKER,
																					// we
																					// don't
																					// need
																					// to
																					// consider
																					// its
																					// subtypes.
			}
			catch (CoreException exc) {
				// Logger logger =
				// ValidationPlugin.getPlugin().getMsgLogger();
				// if (logger.isLoggingLevel(Level.SEVERE)) {
				// LogEntry entry = ValidationPlugin.getLogEntry();
				// entry.setSourceID("TaskListUtility.getValidationTasks(IResource,
				// int)"); //$NON-NLS-1$
				// entry.setTargetException(exc);
				// logger.write(Level.SEVERE, entry);
				// }
				return NO_MARKERS;
			}

			// Now filter in the markers, based on severity type.
			if (allMarkers.length != 0) {
				tempMarkers = new IMarker[allMarkers.length];
				for (int i = 0; i < allMarkers.length; i++) {
					IMarker marker = allMarkers[i];
					Integer filterSeverity = (Integer) marker.getAttribute(VALIDATION_MARKER_SEVERITY);
					if (filterSeverity == null) {
						// odd...marker wasn't created correctly. How could
						// this happen?
						// Default to the current severity and add it to the
						// list.
						try {
							marker.setAttribute(IMarker.SEVERITY, getSeverity(severity));
						}
						catch (CoreException exc) {
							// Logger logger =
							// ValidationPlugin.getPlugin().getMsgLogger();
							// if (logger.isLoggingLevel(Level.SEVERE)) {
							// LogEntry entry =
							// ValidationPlugin.getLogEntry();
							// entry.setSourceID("TaskListUtility.getValidationTasks(int,
							// IResource, int)"); //$NON-NLS-1$
							// entry.setTargetException(exc);
							// logger.write(Level.SEVERE, entry);
							// }
							continue;
						}
						catch (Exception exc) {
							// Logger logger =
							// ValidationPlugin.getPlugin().getMsgLogger();
							// if (logger.isLoggingLevel(Level.SEVERE)) {
							// LogEntry entry =
							// ValidationPlugin.getLogEntry();
							// entry.setSourceID("TaskListUtility.getValidationTasks(int,
							// IResource, int)"); //$NON-NLS-1$
							// entry.setTargetException(exc);
							// logger.write(Level.SEVERE, entry);
							// }
							continue;
						}
					}
					else if ((severity & filterSeverity.intValue()) == 0) {
						continue;
					}
					tempMarkers[validCount++] = marker;
				}
			}
		}
		catch (CoreException exc) {
			// Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			// if (logger.isLoggingLevel(Level.SEVERE)) {
			// LogEntry entry = ValidationPlugin.getLogEntry();
			// entry.setSourceID("TaskListUtility.getValidationTasks(int,
			// IResource, int)"); //$NON-NLS-1$
			// entry.setTargetException(exc);
			// logger.write(Level.SEVERE, entry);
			// }
		}

		if (validCount == 0) {
			return NO_MARKERS;
		}

		IMarker[] validMarkers = new IMarker[validCount];
		System.arraycopy(tempMarkers, 0, validMarkers, 0, validCount);
		return validMarkers;
	}

	private static IMarker[] getValidationTasks(IResource resource, String[] messageOwners, int depth) {
		IMarker[] markers = getValidationTasks(resource, IMessage.ALL_MESSAGES, depth);
		if (markers.length == 0) {
			return NO_MARKERS;
		}

		IMarker[] temp = new IMarker[markers.length];
		int validCount = 0;
		for (int i = 0; i < markers.length; i++) {
			IMarker marker = markers[i];

			try {
				Object owner = marker.getAttribute(VALIDATION_MARKER_OWNER);
				if ((owner == null) || !(owner instanceof String)) {
					// The ValidationMigrator will remove any "unowned"
					// validation markers.
					continue;
				}

				for (int j = 0; j < messageOwners.length; j++) {
					String messageOwner = messageOwners[j];
					if (((String) owner).equals(messageOwner)) {
						temp[validCount++] = marker;
						break;
					}
				}
			}
			catch (CoreException exc) {
				// Logger logger =
				// ValidationPlugin.getPlugin().getMsgLogger();
				// if (logger.isLoggingLevel(Level.SEVERE)) {
				// LogEntry entry = ValidationPlugin.getLogEntry();
				// entry.setSourceID("TaskListUtility.getValidationTasks(project,
				// String[])"); //$NON-NLS-1$
				// entry.setTargetException(exc);
				// logger.write(Level.SEVERE, entry);
				// }
				return NO_MARKERS;
			}
		}

		IMarker[] result = new IMarker[validCount];
		System.arraycopy(temp, 0, result, 0, validCount);
		return result;
	}

	/**
	 * This method retrieves all validation tasks from the resource. If depth
	 * is INFINITE, child tasks are returned as well. Only the tasks which are
	 * owned by the specified messageOwner, and apply to the named IMessage's
	 * target object (objectName) will be returned.
	 */
	private static IMarker[] getValidationTasks(IResource resource, String[] messageOwner, String objectName, String groupName, int depth) throws CoreException {
		if ((messageOwner == null) || (resource == null)) {
			return NO_MARKERS;
		}

		int validCount = 0;
		IMarker[] validList = null;
		IMarker[] markers = getValidationTasks(resource, messageOwner, depth);
		if (markers != null) {
			validList = new IMarker[markers.length];
			for (int i = 0; i < markers.length; i++) {
				IMarker marker = markers[i];

				// If more than one target object resolves to the same
				// resource, removing one target's
				// messages should not remove the other target object's
				// messages.
				if (objectName != null) {
					Object targetObject = marker.getAttribute(VALIDATION_MARKER_TARGETOBJECT);
					if ((targetObject == null) || !(targetObject instanceof String) || !(((String) targetObject).equals(objectName))) {
						continue;
					}
				}

				if (groupName != null) {
					Object group = marker.getAttribute(VALIDATION_MARKER_GROUP);
					if ((group == null) || !(group instanceof String) || !(((String) group).equals(groupName))) {
						continue;
					}
				}

				validList[validCount++] = marker;
			}
		}

		if (validCount == 0) {
			return NO_MARKERS;
		}

		IMarker[] result = new IMarker[validCount];
		System.arraycopy(validList, 0, result, 0, validCount);
		return result;
	}

	/**
	 * This method removes all messages from a resource in the task list.
	 */
	public static void removeAllTasks(IResource resource, String owner, String objectName) throws CoreException {
		removeAllTasks(resource, new String[]{owner}, objectName);
	}

	public static void removeAllTasks(IResource resource, String[] owners, String objectName) throws CoreException {
		removeAllTasks(resource, owners, objectName, getDepth(resource));
	}

	protected static void removeAllTasks(IResource resource, String[] owners, String objectName, int depth) throws CoreException {
		removeTaskSubset(resource, owners, objectName, null, depth); // null
																		// means
																		// no
																		// group
																		// name
	}

	/**
	 * This method removes a subset of tasks from the project, including child
	 * tasks. Every task which belongs to the group, identified by groupName,
	 * will be removed.
	 */
	protected static void removeTaskSubset(IResource resource, String[] owners, String objectName, String groupName, int depth) throws CoreException {
		if ((owners == null) || (resource == null)) {
			return;
		}

		IMarker[] allTasks = getValidationTasks(resource, owners, objectName, groupName, depth);
		if (allTasks.length > 0) {
			ResourcesPlugin.getWorkspace().deleteMarkers(allTasks);
		}
	}
}
