/*******************************************************************************
 * Copyright (c) 2001, 2004 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.validation.internal.operations;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Hashtable;
import java.util.logging.Level;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.wst.validation.core.IMessage;
import org.eclipse.wst.validation.internal.RegistryConstants;
import org.eclipse.wst.validation.internal.plugin.ValidationPlugin;

import com.ibm.wtp.common.logger.LogEntry;
import com.ibm.wtp.common.logger.proxy.Logger;

/**
 * Abstract base class for registration of symbolic model names, and also provides the mechanism for
 * registering the load model method which loads a specific type of MOF model, as identified by the
 * symbolic model name.
 */
public abstract class AWorkbenchHelper implements IWorkbenchHelper {
	private IProject _project = null;
	private Hashtable _modelRegistry = null;
	private static final IContainer[] NO_CONTAINERS = new IContainer[0];
	private int _ruleGroup = RegistryConstants.ATT_RULE_GROUP_DEFAULT;

	public AWorkbenchHelper() {
		super();

		_modelRegistry = new Hashtable();

		registerModel(IRuleGroup.PASS_LEVEL, "loadRuleGroup"); //$NON-NLS-1$
	}

	/**
	 * When the validation is complete, this method will be called so that the IWorkbenchHelper can
	 * clean up any resources it allocated during the validation.
	 * 
	 * If the cleanup is a long-running operation, subtask messages should be sent to the IReporter.
	 */
	public void cleanup(WorkbenchReporter reporter) {
		// Default: nothing to clean up
	}

	/**
	 * When the IProject is closing, perform any cleanup that needs to be done. When this method is
	 * called, if the helper has cached any resources from the IProject, it should release those
	 * resources. If you do not allocate resources in your helper, then this method should be a
	 * no-op.
	 */
	public void closing() {
		closing(getProject());
	}

	/**
	 * When the IProject is closing, perform any cleanup that needs to be done. When this method is
	 * called, if the helper has cached any resources from the IProject, it should release those
	 * resources. If you do not allocate resources in your helper, then this method should be a
	 * no-op.
	 * 
	 * @deprecated Override closing() instead, and use getProject()
	 */
	public void closing(IProject project) {
	}

	/**
	 * When the IProject is being deleted, perform any cleanup that needs to be done. When this
	 * method is called, if the helper has cached any resources from the IProject, it should release
	 * those resources. If you do not allocate resources in your helper, then this method should be
	 * a no-op.
	 */
	public void deleting() {
		deleting(getProject());
	}

	/**
	 * When the IProject is being deleted, perform any cleanup that needs to be done. When this
	 * method is called, if the helper has cached any resources from the IProject, it should release
	 * those resources. If you do not allocate resources in your helper, then this method should be
	 * a no-op.
	 * 
	 * @deprecated Override deleting() instead, and use getProject()
	 */
	public void deleting(IProject project) {
	}

	/**
	 * Returns the IPath of a resource, relative to the container. If the IResource is not a member
	 * of the container, return null. This method should be useful for implementors of this class;
	 * specifically, in their getPortableName method.
	 */
	public static String getContainerRelativePath(String fullPath, IContainer container) {
		if ((fullPath == null) || (container == null))
			return null;
		IPath relPath = getContainerRelativePath(new Path(fullPath), container);
		if (relPath != null)
			return relPath.toString();
		return null;
	}

	/**
	 * Returns the IPath of a resource, relative to the container. If the IResource is not a member
	 * of the container, return null. This method should be useful for implementors of this class;
	 * specifically, in their getPortableName method.
	 */
	public static IPath getContainerRelativePath(IResource resource, IContainer container) {
		if ((resource == null) || (container == null)) {
			return null;
		}

		IResource foundResource = null;
		IPath relPath = getContainerRelativePath(resource.getFullPath(), container);
		if (relPath != null) {
			// if relPath is null, the resource is not a direct member of the container
			try {
				if (!resource.exists()) { // findMember won't work
					if (resource instanceof IFile) {
						foundResource = container.getFile(relPath);
					} else if (resource instanceof IFolder) {
						foundResource = container.getFolder(relPath);
					}
				} else {
					foundResource = container.findMember(relPath, true); // true means include
					// phantom resources
					if ((foundResource != null) && !foundResource.exists()) {
						foundResource = null;
					}
				}
			} catch (IllegalArgumentException exc) {
				foundResource = null;

				Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
				if (logger.isLoggingLevel(Level.SEVERE)) {
					LogEntry entry = ValidationPlugin.getLogEntry();
					entry.setSourceID("AWorkbenchHelper::getContainerRelativePath(IResource, IContainer)"); //$NON-NLS-1$
					entry.setTargetException(exc);
					logger.write(Level.SEVERE, entry);
				}
			}
		}

		if (foundResource == null) {
			return null;
		}

		// file has been found
		int matchingFirstSegments = container.getProjectRelativePath().matchingFirstSegments(resource.getProjectRelativePath());
		return resource.getProjectRelativePath().removeFirstSegments(matchingFirstSegments);
	}

	/**
	 * Given an IPath, if the IPath is absolute, and is a part of the IContainer, return an IPath
	 * which is relative to the container. If the IPath is not part of the IContainer, return null.
	 */
	public static IPath getContainerRelativePath(IPath path, IContainer container) {
		if ((path == null) || (container == null)) {
			return null;
		}

		if (path.isAbsolute()) {
			// Is the path part of the IContainer?
			int matchingFirstSegments = path.matchingFirstSegments(container.getFullPath());
			if ((matchingFirstSegments > 0) && (matchingFirstSegments == container.getFullPath().segmentCount())) {
				// part of the IContainer
				return path.removeFirstSegments(matchingFirstSegments);
			}
			// not part of the IContainer
			return null;
		}
		// path is relative
		// Is the path part of the IContainer?
		//TODO don't have time to implement this now, but should in future. - Ruth
		return null;
	}

	/**
	 * Given an IMessage's target object, return a string which identifies the object, so that the
	 * user can locate it.
	 */
	public String getDescription(Object object) {
		if (object == null) {
			return ""; //$NON-NLS-1$
		}

		if (object instanceof WorkbenchFileDelta) {
			WorkbenchFileDelta wfd = (WorkbenchFileDelta) object;
			if (wfd.getResource() != null) {
				// resource will be null if WorkbenchFileDelta was constructed from an Object
				// instead of an IResource
				return wfd.getResource().getFullPath().toString();
			}
		}

		return object.toString();
	}

	/**
	 * Given an Object, if the object has a corresponding IFile in the workbench, return the IFile.
	 * Otherwise return null.
	 * 
	 * This method is used by the WorkbenchReporter. In eclipse, in order to add or remove a task
	 * list entry, the IResource, to which the entry applies, must be identified. The IReporter
	 * interface passes in an Object in these methods:
	 * 
	 * addValidationMessage(IValidator, IMessage) // Object is a part of IMessage
	 * 
	 * removeAllMessages(IValidator, Object),
	 * 
	 * Thus, the WorkbenchReporter needs to know how, given the Object, which IFile that the Object
	 * represents in the workbench, in order to be able to add the task list entry.
	 * 
	 * If this method returns null, then the WorkbenchReporter will add the message to the IProject
	 * instead of an IFile.
	 *  
	 */
	public IFile getFile(Object obj) {
		return null;
	}

	public IResource getResource(Object obj) {
		if (obj == null) {
			return null;
		}

		IResource res = null;
		if (obj instanceof WorkbenchFileDelta) {
			// resource may be null if WorkbenchFileDelta was constructed from an Object instead of
			// an IResource
			res = ((WorkbenchFileDelta) obj).getResource();
		} else if (obj instanceof IResource) {
			res = (IResource) obj;
		}

		if ((res == null) || (!res.exists())) {
			return getFile(obj);
		}

		return res;
	}

	/**
	 * If the IProject is associated with an EJBNatureRuntime, return the IJavaProject which
	 * represents it.
	 */
	public static IJavaProject getJavaProject(IProject project) {
		if (project == null) {
			return null;
		}
		return JavaCore.create(project);
	}

	/**
	 * Given an IMessage's target object, return the line number, of the IFile, which the target
	 * object represents. If the object is null, or if access to line numbers is not possible,
	 * return "0".
	 */
	public int getLineNo(Object object) {
		IResourceUtil util = ValidatorManager.getResourceUtil();
		if (util == null) {
			return IMessage.LINENO_UNSET;
		}
		try {
			return util.getLineNo(object);
		} catch (Throwable exc) {
			Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = ValidationPlugin.getLogEntry();
				entry.setSourceID("AWorkbenchHelper.getLineNo(Object)"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			return IMessage.LINENO_UNSET;
		}

	}

	/**
	 * Given an IMessage's target object, return the line number, of the IFile, which the target
	 * object represents, if possible. If the object is null, or if access to line numbers is not
	 * possible, return a text description of the location.
	 * 
	 * This method will be called whether or not the IResource is an IFile, IFolder, or IProject.
	 * Line numbers are valid only for IFile types; if the resource is not an IFile, then a text
	 * description of the location must be returned.
	 */
	public String getLocation(Object object) {
		IResource res = getResource(object);
		if ((res == null) || !(res instanceof IFile))
			// return a text description
			return getDescription(object);
		// default to a line number, if it's available. Else, use a text description.
		int lineNumber = getLineNo(object);
		if (lineNumber == IMessage.LINENO_UNSET) {
			return getDescription(object);
		}
		// return the line number
		return String.valueOf(lineNumber);
	}

	/**
	 * Given a name of a load method, and the types of parameters it takes (this method is always
	 * called with null as the second parameter), return the java.lang.reflect.Method which
	 * represents the load method.
	 */
	private final Method getMethod(String methodName, Class[] parmTypes) {
		Method m = null;
		try {
			m = getClass().getMethod(methodName, parmTypes);
		} catch (NoSuchMethodException exc) {
			Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = ValidationPlugin.getLogEntry();
				entry.setSourceID("AWorkbenchHelper::getMethod(String, Class[])"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			return null;
		}

		return m;
	}

	/**
	 * @see IWorkbenchHelper.getPortableName(IResource)
	 */
	public String getPortableName(IResource resource) {
		return resource.getFullPath().toString();
	}

	/**
	 * Return the IProject which is about to be validated. Each IWorkbenchHelper knows how to
	 * traverse a certain type of IProject, for example, an EJB project or a web project.
	 */
	public final IProject getProject() {
		return _project;
	}

	/**
	 * Return the folders (or project) which contain the .java source files.
	 */
	public static IContainer[] getProjectSourceContainers(IProject project) {
		if (project == null) {
			return NO_CONTAINERS;
		}

		IJavaProject jp = getJavaProject(project);
		if (jp == null) {
			return NO_CONTAINERS;
		}

		return getProjectSourceContainers(jp);
	}

	/**
	 * Return the folders (or project) which contain the .java source files.
	 */
	public static IContainer[] getProjectSourceContainers(IJavaProject javaProject) {
		if (javaProject == null) {
			return NO_CONTAINERS;
		}
		IProject project = javaProject.getProject();

		IClasspathEntry[] classpath = null;
		try {
			classpath = javaProject.getResolvedClasspath(true); // true means ignore unresolved
			// (missing) variables, instead of
			// throwing an exception
		} catch (JavaModelException exc) {
			Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = ValidationPlugin.getLogEntry();
				entry.setSourceID("AWorkbenchHelper::getProjectSourceContainers(IJavaProject)"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			return NO_CONTAINERS;
		}

		if (classpath == null) {
			return NO_CONTAINERS;
		}

		// Traverse the classpath, and calculate a list of just the
		// IFolders and IProjects (i.e., IContainers) which contain source
		IContainer[] icontainers = new IContainer[classpath.length];
		int validCount = 0;
		for (int i = 0; i < classpath.length; i++) {
			IClasspathEntry entry = classpath[i];
			if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
				IPath entryPath = entry.getPath();
				IPath relEntryPath = getContainerRelativePath(entryPath, project);
				if (relEntryPath == null) {
					// classpath entry refers to something which doesn't exist
					continue;
				}

				IResource outputResource = project.findMember(relEntryPath);
				if (outputResource == null) {
					// classpath entry refers to something which doesn't exist
					continue;
				}

				if (outputResource instanceof IContainer) {
					icontainers[validCount++] = (IContainer) outputResource;
				}
			}
		}

		//  following line causes a ClassCastException, so construct an array of IContainers
		// explicitly
		//	return (IContainer[])icontainers.toArray();
		IContainer[] containers = new IContainer[validCount];
		System.arraycopy(icontainers, 0, containers, 0, validCount);
		return containers;
	}

	public int getRuleGroup() {
		return _ruleGroup;
	}

	/**
	 * This method can be overriden by AWorkbenchHelpers, if they wish to perform some
	 * initialization once the IProject is set. Default is to do nothing.
	 * 
	 * For example, if this IWorkbenchHelper delegates to another IWorkbenchHelper, then that
	 * IWorkbenchHelper's setProject() method should be called here.
	 */
	public void initialize() {
	}

	/**
	 * Return true if the given resource is in an IJavaProject, and if it is in one of the source
	 * folders in the IJavaProject. If the project's source folder happens to be the project's
	 * output folder too, this method will return true. If res is null, or is not found in one of
	 * the source containers, this method will return false.
	 */
	public boolean isInJavaSourcePath(IResource res) {
		if (res == null) {
			return false;
		}

		IContainer[] containers = getProjectSourceContainers(res.getProject());
		for (int c = 0; c < containers.length; c++) {
			IPath resourcePath = getContainerRelativePath(res, containers[c]);
			if (resourcePath != null) {
				// file has been found
				return true;
			}
		}

		return false;
	}

	/**
	 * Return true if the given symbolic name is registered, and can be loaded by AWorkbenchHelper's
	 * "loadModel" method. For further information, see the comment above AWorkbenchHelper's
	 * "registerModel" method.
	 */
	public final boolean isRegistered(String symbolicName) {
		if (symbolicName == null) {
			return false;
		}
		return _modelRegistry.containsKey(symbolicName);
	}

	/**
	 * Given a symbolic name, load the MOF model which is identified by that name.
	 * 
	 * For support of dynamic symbolic names, such as file names, read the comment above the
	 * registerModel method.
	 * 
	 * @see registerModel
	 */
	public Object loadModel(String symbolicName) {
		return loadModel(symbolicName, null);
	}

	/**
	 * Given a symbolic name, load the MOF model which is identified by that name.
	 * 
	 * For support of dynamic symbolic names, such as file names, read the comment above the
	 * registerModel method.
	 * 
	 * @see registerModel
	 */
	public Object loadModel(String symbolicName, Object[] parms) {
		try {
			Method loader = (Method) _modelRegistry.get(symbolicName);
			if (loader == null) {
				return null;
			}

			return loader.invoke(this, parms);
		} catch (IllegalAccessException exc) {
			Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = ValidationPlugin.getLogEntry();
				entry.setSourceID("AWorkbenchHelper::loadModel(String, Object[])"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			return null;
		} catch (InvocationTargetException exc) {
			Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = ValidationPlugin.getLogEntry();
				entry.setSourceID("AWorkbenchHelper::loadModel(String, Object[])"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);

				if (exc.getTargetException() != null) {
					entry.setTargetException(exc.getTargetException());
					logger.write(Level.SEVERE, exc);
				}
			}
			return null;
		} catch (NullPointerException exc) {
			Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = ValidationPlugin.getLogEntry();
				entry.setSourceID("AWorkbenchHelper::loadModel(String, Object[])"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			return null;
		} catch (ExceptionInInitializerError exc) {
			Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			if (logger.isLoggingLevel(Level.SEVERE)) {
				LogEntry entry = ValidationPlugin.getLogEntry();
				entry.setSourceID("AWorkbenchHelper::loadModel(String, Object[])"); //$NON-NLS-1$
				entry.setTargetException(exc);
				logger.write(Level.SEVERE, entry);
			}
			return null;
		}
	}

	public Object loadRuleGroup() {
		return new Integer(getRuleGroup()); // have to wrap the int in an Integer because can't cast
		// an int to an Object
	}

	/**
	 * This method should be used only by the validation framework. This method will be called by
	 * ValidationOperation, before the IValidator's validate method is called, to set the group of
	 * rules which the IValidator should check.
	 */
	public void setRuleGroup(int rg) {
		_ruleGroup = rg;
	}

	/**
	 * Register a load method for a symbolic name. A load method is defined as a method which takes
	 * no parameters and returns a RefObject.
	 * 
	 * Every subclass of AWorkbenchHelper, for every static type of symbolic name which it supports,
	 * should call registerModel. For IWorkbenchHelpers which support dynamic symbolic names, such
	 * as file names, each IWorkbenchHelper should override the "loadModel" method. Their
	 * "loadModel" should first call this class' "isRegistered" method to see if they're dealing
	 * with a static symbolic name, or a dynamic one. If the symbolic name is registered, the
	 * child's "loadModel" method should just return the result of AWorkbenchHelper's "loadModel"
	 * method. Otherwise, it should return the result based on its own processing.
	 * 
	 * When this method is called, the load method identified by loadMethodName is located & stored
	 * for future retrieval by the "loadModel" method. When the IValidator calls "loadModel" with a
	 * symbolic name, the java.lang.reflect.Method which was loaded by this method is invoked, and
	 * the result (RefObject) returned by that method is returned by "loadModel".
	 * 
	 * symbolicName must not be null or the empty string. loadMethodName must not be null or the
	 * empty string.
	 */
	protected final void registerModel(String symbolicName, String loadMethodName) {
		registerModel(symbolicName, loadMethodName, null);
	}

	/**
	 * Register a load method for a symbolic name. A load method is defined as a method which takes
	 * no parameters and returns a RefObject.
	 * 
	 * Every subclass of AWorkbenchHelper, for every static type of symbolic name which it supports,
	 * should call registerModel. For IWorkbenchHelpers which support dynamic symbolic names, such
	 * as file names, each IWorkbenchHelper should override the "loadModel" method. Their
	 * "loadModel" should first call this class' "isRegistered" method to see if they're dealing
	 * with a static symbolic name, or a dynamic one. If the symbolic name is registered, the
	 * child's "loadModel" method should just return the result of AWorkbenchHelper's "loadModel"
	 * method. Otherwise, it should return the result based on its own processing.
	 * 
	 * When this method is called, the load method identified by loadMethodName is located & stored
	 * for future retrieval by the "loadModel" method. When the IValidator calls "loadModel" with a
	 * symbolic name, the java.lang.reflect.Method which was loaded by this method is invoked, and
	 * the result (RefObject) returned by that method is returned by "loadModel".
	 * 
	 * symbolicName must not be null or the empty string. loadMethodName must not be null or the
	 * empty string.
	 */
	protected final void registerModel(String symbolicName, String loadMethodName, Class[] parms) {
		Method method = getMethod(loadMethodName, parms);
		if (method == null) {
			Logger logger = ValidationPlugin.getPlugin().getMsgLogger();
			if (logger.isLoggingLevel(Level.FINE)) {
				StringBuffer buffer = new StringBuffer("Load method "); //$NON-NLS-1$
				buffer.append(loadMethodName);
				buffer.append("("); //$NON-NLS-1$
				for (int i = 0; (parms != null) && (i < parms.length); i++) {
					buffer.append(parms[i]);
				}
				buffer.append(") must exist. " + getClass().getName() + " cannot support model " + symbolicName); //$NON-NLS-1$ //$NON-NLS-2$

				LogEntry entry = ValidationPlugin.getLogEntry();
				entry.setSourceID("ValidationRegistryReader.readExtension(IExtension)"); //$NON-NLS-1$
				entry.setText(buffer.toString());
				logger.write(Level.FINE, entry);
			}
		} else {
			_modelRegistry.put(symbolicName, method);
		}
	}

	/**
	 * Whether full or incremental validation is running, this method will be called, for every
	 * IResource which is filtered in by the IValidator, so that the IHelper can receive
	 * notification that one of the resources, which validation will run on, is being filtered in.
	 */
	public void registerResource(IResource resource) {
		// default: do nothing
	}

	/**
	 * This method is called by the Validation Framework, to initialize the IWorkbenchHelper so that
	 * it can gather information from the current project.
	 * 
	 * If an IWorkbenchHelper delegates some model loading to another IWorkbenchHelper, this method
	 * should be overriden so that the delegatee IWorkbenchHelper is initialized with the IProject.
	 */
	public final void setProject(IProject project) {
		_project = project;

		if (project != null) {
			// Project will be set back to null once the validation of the project is complete.
			initialize();
		}
	}

	/**
	 * Notifies this IWorkbenchHelper that the Validation Framework is shutting down. There will be
	 * calls to closing(IProject) and possibly deleting(IProject) following this call, but the
	 * resources may already be closed by the time that those methods are called, so EVERYTHING
	 * should be cleaned up in this method. The parameter passed in is the project which is about to
	 * shut down. This method will be called once for every IProject in the workbench. The IProject
	 * may, or may not, be closed.
	 */
	public void shutdown() {
		// Default is to assume that no resources were allocated; therefore,
		// no cleanup needs to be done.
		shutdown(getProject());
	}

	/**
	 * Notifies this IWorkbenchHelper that the Validation Framework is shutting down. There will be
	 * calls to closing(IProject) and possibly deleting(IProject) following this call, but the
	 * resources may already be closed by the time that those methods are called, so EVERYTHING
	 * should be cleaned up in this method. The parameter passed in is the project which is about to
	 * shut down. This method will be called once for every IProject in the workbench. The IProject
	 * may, or may not, be closed.
	 * 
	 * @deprecated Override shutdown() instead, and use getProject()
	 */
	public void shutdown(IProject project) {
		// Default is to assume that no resources were allocated; therefore,
		// no cleanup needs to be done.
	}
}