/*******************************************************************************
 * 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.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
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 DuplicateClassFolderEntry = "DuplicateClassFolderEntry"; //$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);				
				final ClasspathDependencyValidatorData data = new ClasspathDependencyValidatorData(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 boolean isClassFolder = ClasspathDependencyUtil.isClassFolderEntry(entry);
					final IClasspathAttribute attrib = (IClasspathAttribute) referencedRawEntries.get(entry);
					final IPath runtimePath = ClasspathDependencyUtil.getRuntimePath(attrib, isWebApp, isClassFolder);
					if (runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH)) {
						hasRootMapping = true;
					}
					IMessage[] msgs = validateVirtualComponentEntry(entry, attrib, isWebApp, proj, data);
					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, data);
							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) {
		return validateVirtualComponentEntry(entry, attrib, isWebApp, project, new ClasspathDependencyValidatorData(project));
	}
	
	/**
	 * Holds data required to validate classpath dependencies for a specific project. Can be computed once for the project and reused.
	 *
	 */
	public static class ClasspathDependencyValidatorData {
		private final IProject project;
		// Class folders mapped via the component file (either directly or via src folders)
		private final IContainer[] mappedClassFolders;
		
		public ClasspathDependencyValidatorData(final IProject project) {
			this.project = project;
			this.mappedClassFolders = J2EEProjectUtilities.getAllOutputContainers(project);
		}
		
		public IProject getProject() {
			return project;
		}
		
		public IContainer[] getMappedClassFolders() {
			return mappedClassFolders;
		}
	}
	
	/**
	 * 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.
	 * @param project The parent project.
	 * @param data Data required for validation. Can be computed once for the project and reused.
	 * @return IMessages representing validation results.
	 */
	public static IMessage[] validateVirtualComponentEntry(final IClasspathEntry entry, final IClasspathAttribute attrib, final boolean isWebApp, final IProject project, 
			final ClasspathDependencyValidatorData data) {
		List results = new ArrayList();
		if (entry == null) {
			return (IMessage[]) results.toArray(new IMessage[results.size()]);
		}
		
		final int kind = entry.getEntryKind();
		final boolean isFile = !ClasspathDependencyUtil.isClassFolderEntry(entry);
		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) {
			if (!isFile) {
				final IContainer[] mappedClassFolders = data.getMappedClassFolders();
				final IResource resource = ClasspathDependencyUtil.getEntryResource(entry);
				if (resource != null) {
					final IPath fullClassFolderPath = resource.getFullPath();
					boolean alreadyMapped = false;
					for (int j = 0; j < mappedClassFolders.length; j++) {
						if (fullClassFolderPath.equals(mappedClassFolders[j].getFullPath())) {
							// entry resolves to same file as existing class folder mapping, skip
							alreadyMapped = true;
							break;
						}
					} 

					// Class folder reference; ensure this is not already mapped via the component file.
					if (alreadyMapped) {
						results.add(new Message("classpathdependencyvalidator", // $NON-NLS-1$
								IMessage.HIGH_SEVERITY, DuplicateClassFolderEntry, new String[]{entry.getPath().toString()}, project));
					}
				}
			}
		}
    	
    	final IPath runtimePath = ClasspathDependencyUtil.getRuntimePath(attrib, isWebApp, !isFile);
    	if (!isWebApp) {
    		// only a ../ or / mapping is currently legal in a non-web context
    		if (!(runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_CONTAINER_PATH) 
    				|| runtimePath.equals(IClasspathDependencyConstants.RUNTIME_MAPPING_INTO_COMPONENT_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) 
    			&& !runtimePath.equals(IClasspathDependencyConstants.WEB_INF_LIB_PATH)
    			&& !runtimePath.equals(IClasspathDependencyConstants.WEB_INF_CLASSES_PATH)) { 
    			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);
	}
}
