/*******************************************************************************
 * Copyright (c) 2001, 2007 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.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.ui.internal.HTMLUIPlugin;
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 = HTMLUIPlugin.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);
		}
	}
}
