/*******************************************************************************
 * Copyright (c) 2006 2007 BEA Systems, Inc. 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:
 * BEA Systems, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.classpathdep;


import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.classpathdep.IClasspathDependencyConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.eclipse.wst.validation.internal.provisional.core.IValidationContext;
import org.eclipse.wst.validation.internal.provisional.core.IValidatorJob;

/**
 * Validates classpath entries that have been tagged as component dependencies.
 */
public class ClasspathDependencyValidator implements IValidatorJob {
	
	public static final String AppClientProject = "AppClientProject"; //$NON-NLS-1$
	public static final String RootMappingNonEARWARRef = "RootMappingNonEARWARRef"; //$NON-NLS-1$
	public static final String NonTaggedExportedClasses = "NonTaggedExportedClasses"; //$NON-NLS-1$
	public static final String DuplicateArchiveName = "DuplicateArchiveName"; //$NON-NLS-1$
	public static final String ProjectClasspathEntry = "ProjectClasspathEntry"; //$NON-NLS-1$
	public static final String SourceEntry = "SourceEntry"; //$NON-NLS-1$
	public static final String FilteredContainer = "FilteredContainer"; //$NON-NLS-1$
	public static final String ClassFolderEntry = "ClassFolderEntry"; //$NON-NLS-1$
	public static final String NonWebNonExported = "NonWebNonExported"; //$NON-NLS-1$
	public static final String InvalidNonWebRuntimePath = "InvalidNonWebRuntimePath"; //$NON-NLS-1$
	public static final String InvalidWebRuntimePath = "InvalidWebRuntimePath"; //$NON-NLS-1$
	
	protected IReporter _reporter;
	
	public ClasspathDependencyValidator() {
		super();
	}
	
	public IStatus validateInJob(IValidationContext helper, IReporter reporter)
			throws ValidationException {
		_reporter = reporter;
		//Remove all markers related to this validator
		_reporter.removeAllMessages(this);
		//Using the helper class, load the module model
		final Set archiveNames = new HashSet();
		final IProject proj = ((ClasspathDependencyValidatorHelper) helper).getProject();
		try {
			if (proj.isAccessible() 
			    && proj.hasNature(ModuleCoreNature.MODULE_NATURE_ID)
			    && proj.hasNature(JavaCore.NATURE_ID)) {
			    
				final IJavaProject javaProject = JavaCore.create(proj);
			    final boolean isWebApp = J2EEProjectUtilities.isDynamicWebProject(proj);
				final Map referencedRawEntries = ClasspathDependencyUtil.getRawComponentClasspathDependencies(javaProject); 				
				final List potentialRawEntries = ClasspathDependencyUtil.getPotentialComponentClasspathDependencies(javaProject);
				final IVirtualComponent component = ComponentCore.createComponent(proj);				
				
				// validate the raw referenced container entries
				Iterator i =  referencedRawEntries.keySet().iterator();
				boolean hasRootMapping = false;
				while (i.hasNext()) {
					final IClasspathEntry entry = (IClasspathEntry) i.next();
					final IClasspathAttribute attrib = (IClasspathAttribute) referencedRawEntries.get(entry);
					final IPath runtimePath = ClasspathDependencyUtil.getRuntimePath(attrib, isWebApp);
					if (runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
						hasRootMapping = true;
					}
					IMessage[] msgs = validateVirtualComponentEntry(entry, attrib, isWebApp, proj);
					final String cpEntryPath = entry.getPath().toString();
					for (int j = 0; j < msgs.length; j++) {
						msgs[j].setGroupName(cpEntryPath);
					}
					reportMessages(msgs);
		    		// if not a web app, warn if associated cp entry is not exported
					if (!isWebApp && !entry.isExported()) {
						_reporter.addMessage(this, new Message("classpathdependencyvalidator", // $NON-NLS-1$
								IMessage.NORMAL_SEVERITY, NonWebNonExported, new String[]{cpEntryPath}, proj));
					}
				}
			
				if (!referencedRawEntries.isEmpty()) {
					if (J2EEProjectUtilities.isApplicationClientProject(proj)) { 
						// classpath component dependencies are not supported for application client projects
						final IMessage msg = new Message("classpathdependencyvalidator", // $NON-NLS-1$
								IMessage.HIGH_SEVERITY, AppClientProject, null, proj);
						_reporter.addMessage(this, msg);
					}

					// are there any root mappings
					if (hasRootMapping && component != null) {
						boolean referencedFromEARorWAR = false;
						final List earWarRefs = new ArrayList();
						final IVirtualComponent[] refComponents = component.getReferencingComponents();
						for (int j = 0; j < refComponents.length; j++) {
							if (J2EEProjectUtilities.isEARProject(refComponents[j].getProject())
									|| J2EEProjectUtilities.isDynamicWebProject(refComponents[j].getProject())) {
								referencedFromEARorWAR = true;
								earWarRefs.add(refComponents[j]);
							}
						}
						if (!referencedFromEARorWAR) {
							// warn if there are root mappings and the project is not referenced by an EAR or a WAR
							final IMessage msg =new Message("classpathdependencyvalidator", // $NON-NLS-1$
									IMessage.NORMAL_SEVERITY, RootMappingNonEARWARRef, null, proj); 
							_reporter.addMessage(this, msg);
						}
					}
				}
				
				// generate warning messages for any potential entries; we warn for these since
				// the classes are being exposed but will not be bundled into the exported/published module and
				// therefore will not be available at runtime.
				i = potentialRawEntries.iterator();
				while (i.hasNext()) {
					final IClasspathEntry entry = (IClasspathEntry) i.next();
					final IMessage msg =new Message("classpathdependencyvalidator", // $NON-NLS-1$
							IMessage.NORMAL_SEVERITY, NonTaggedExportedClasses, new String[]{entry.getPath().toString()}, proj);
					msg.setGroupName(entry.getPath().toString());
					_reporter.addMessage(this, msg); 
				}
				
				// validate all resolved entries (only perform this if there are raw referenced entries)
				if (!referencedRawEntries.isEmpty()) {
					final Map referencedResolvedEntries = ClasspathDependencyUtil.getComponentClasspathDependencies(javaProject, isWebApp, false);  
					i = referencedResolvedEntries.keySet().iterator();
					while (i.hasNext()) {
						final IClasspathEntry entry = (IClasspathEntry) i.next();
						final IClasspathAttribute attrib = (IClasspathAttribute) referencedResolvedEntries.get(entry);
						// compute the archive name
						final String archivePath = ClasspathDependencyUtil.getArchiveName(entry);
						if (archiveNames.contains(archivePath)) {
							// Project cp entry
							final IMessage msg = new Message("classpathdependencyvalidator", // $NON-NLS-1$
									IMessage.HIGH_SEVERITY, DuplicateArchiveName, new String[]{entry.getPath().toString()}, proj);									
							_reporter.addMessage(this, msg); 
						} else {
							archiveNames.add(archivePath);
						}
						// validate the resolved entry if we didn't already validate as part of the raw entries
						if (!referencedRawEntries.containsKey(entry)) {
							IMessage[] msgs = validateVirtualComponentEntry(entry, attrib, isWebApp, proj);
							reportMessages(msgs);
						}
					}
				}
			}
		} catch (CoreException e) {
			Logger.getLogger(J2EEPlugin.PLUGIN_ID).logError(e);
		}
		
		return Status.OK_STATUS;
	}
	
	private void reportMessages(final IMessage[] msgs) {
		for (int i = 0; i < msgs.length; i++) {
			_reporter.addMessage(this, msgs[i]);
		}
	}
	
	/**
	 * Checks if the specified Java classpath entry is a valid WTP virtual component reference.
	 * Does not check the runtime path.
	 * @param entry Raw or resolved classpath entry to validate. 
	 * @param attrib The WTP classpath component dependency attribute. Null if it has not yet been set.
	 * @param isWebApp True if the target project is associated with a web project.
	 * @return IMessages representing validation results.
	 */
	public static IMessage[] validateVirtualComponentEntry(final IClasspathEntry entry, final IClasspathAttribute attrib, final boolean isWebApp, final IProject project) {
		List results = new ArrayList();
		if (entry == null) {
			return (IMessage[]) results.toArray(new IMessage[results.size()]);
		}
		
		final int kind = entry.getEntryKind();
		if (kind == IClasspathEntry.CPE_PROJECT) {
			
			// Project cp entry
			results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$
					IMessage.HIGH_SEVERITY, ProjectClasspathEntry, new String[]{entry.getPath().toString()}, project));

			return (IMessage[]) results.toArray(new IMessage[results.size()]);
		} else if (kind == IClasspathEntry.CPE_SOURCE) {
			
			// Source cp entry
			
			results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$
					IMessage.HIGH_SEVERITY, SourceEntry, new String[]{entry.getPath().toString()}, project));
			return (IMessage[]) results.toArray(new IMessage[results.size()]);
		} else if (kind == IClasspathEntry.CPE_CONTAINER) {

			// get the set of classpath container IDs that should be filtered
			List filteredIDs = ClasspathDependencyExtensions.get().getFilteredClasspathContainerIDs();
			final IPath path = entry.getPath();
			for (int i = 0; i < filteredIDs.size(); i++) {
				final String id = (String) filteredIDs.get(i);
				if (path.segment(0).equals(id)) {
	        		// filtered classpath container
	    			results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$
	    					IMessage.HIGH_SEVERITY, FilteredContainer, new String[]{entry.getPath().toString()}, project));
	    			return (IMessage[]) results.toArray(new IMessage[results.size()]);					
				}
			}

		} else if (kind == IClasspathEntry.CPE_LIBRARY) {
			// does the path refer to a file or a folder?
			final IPath entryPath = entry.getPath();
			IPath entryLocation = entryPath;
			final IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(entryPath);
			if (resource != null) {
				entryLocation = resource.getLocation();
			}
			boolean isFile = true; // by default, assume a jar file
			if (entryLocation.toFile().isDirectory()) {
				isFile = false;
			}
				
			if (!isFile) {
				// Class folder reference
				results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$
						IMessage.HIGH_SEVERITY, ClassFolderEntry, new String[]{entry.getPath().toString()}, project));
			}
		}
    	
    	final IPath runtimePath = ClasspathDependencyUtil.getRuntimePath(attrib, isWebApp);
    	if (!isWebApp) {
    		// only a ../ mapping is currently legal in a non-web context
    		if (!runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
    			results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$
    					IMessage.HIGH_SEVERITY, InvalidNonWebRuntimePath, new String[]{entry.getPath().toString(), runtimePath.toString()}, project));
    		}
    	} else {
    		String pathStr = runtimePath.toString();
    		// can only be ../, /WEB-INF/lib or /WEB-INF/classes
    		if (!runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH) 
    			&& !pathStr.equals("/WEB-INF/lib")
    			&& !pathStr.equals("/WEB-INF/classes")) { 
    			results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$
    					IMessage.HIGH_SEVERITY, InvalidWebRuntimePath, new String[]{entry.getPath().toString(), pathStr}, project));
    		}
    	}

		return (IMessage[]) results.toArray(new IMessage[results.size()]);
	}
	
	public ISchedulingRule getSchedulingRule(IValidationContext helper) {
		return null;
	}

	public void cleanup(IReporter reporter) {
		_reporter = null;

	}

	public void validate(IValidationContext helper, IReporter reporter)
			throws ValidationException {
		// Forwarding to job method
		validateInJob(helper, reporter);
	}
}
