/*******************************************************************************
 * Copyright (c) 2003, 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.jst.j2ee.internal.web.validation;



import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.resources.IFile;
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.Path;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.jst.j2ee.classpathdep.ClasspathDependencyUtil;
import org.eclipse.jst.j2ee.componentcore.J2EEModuleVirtualComponent;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.jst.j2ee.model.internal.validation.WarValidator;
import org.eclipse.jst.j2ee.web.componentcore.util.WebArtifactEdit;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.internal.resources.VirtualArchiveComponent;
import org.eclipse.wst.common.componentcore.internal.util.ComponentUtilities;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.common.componentcore.resources.IVirtualFolder;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;
import org.eclipse.wst.common.componentcore.resources.IVirtualResource;
import org.eclipse.wst.validation.internal.core.Message;
import org.eclipse.wst.validation.internal.core.ValidationException;
import org.eclipse.wst.validation.internal.operations.IWorkbenchContext;
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;


/**
 * Insert the type's description here. Creation date: (10/2/2001 6:46:56 PM)
 * 
 * @author: Administrator
 */
public class UIWarValidator extends WarValidator {
	
	protected org.eclipse.jst.j2ee.internal.web.validation.UIWarHelper warHelper;	




	/**
	 * UIWarValidator constructor comment.
	 */
	public UIWarValidator() {
		super();
	}

	/**
	 * Insert the method's description here. Creation date: (10/2/2001 8:01:45 PM)
	 * 
	 * @return org.eclipse.wst.validation.internal.core.core.war.workbenchimpl.UIWarHelper
	 */
	public org.eclipse.jst.j2ee.internal.web.validation.UIWarHelper getWarHelper() {
		return warHelper;
	}

	/**
	 * Insert the method's description here. Creation date: (10/2/2001 8:01:45 PM)
	 * 
	 * @param newWarHelper
	 *            org.eclipse.wst.validation.internal.core.core.war.workbenchimpl.UIWarHelper
	 */
	public void setWarHelper(org.eclipse.jst.j2ee.internal.web.validation.UIWarHelper newWarHelper) {
		warHelper = newWarHelper;
	}

	/**
	 * Insert the method's description here. Creation date: (10/2/2001 6:49:26 PM)
	 */
	public void validate() throws ValidationException {
		// First remove all previous msg. for this project
		//	_reporter.removeAllMessages(this,null);
		super.validate();
		validateEARForContextRoot();
	}

	/**
	 * Insert the method's description here. Creation date: (10/2/2001 6:49:26 PM)
	 */
	public IStatus validateInJob(IValidationContext inHelper, IReporter inReporter)
			throws org.eclipse.wst.validation.internal.core.ValidationException {
		
		setWarHelper((UIWarHelper) inHelper);
		IProject proj = ((IWorkbenchContext) warHelper).getProject();
		IVirtualComponent wbModule = ComponentCore.createComponent(proj);
        if( wbModule != null && J2EEProjectUtilities.isDynamicWebProject(proj)) {           	
        	IVirtualFile webFile = wbModule.getRootFolder().getFile(J2EEConstants.WEBAPP_DD_URI);
			if( webFile.exists()) {
				status = super.validateInJob(inHelper, inReporter);
				validateWebInfLibs(wbModule);
			}
        }
        return status;
	}	

	/*
	 * For web projects, need to validate that the classpath component dependencies (both
	 * from this project's classpath and from the exported classpath entries of referenced
	 * utility projects) do not conflict.
	 */
	private void validateWebInfLibs(final IVirtualComponent component) {

		final Set webLibMappings = new HashSet();
		
		// get the libs currently in the WEB-INF/lib folder
		final IVirtualFolder folder = component.getRootFolder().getFolder(WebArtifactEdit.WEBLIB);
		try {
			IVirtualResource[] resources = folder.members();
			for (int i = 0; i < resources.length; i++) {
				if (resources[i] instanceof IVirtualFile) {
					IResource[] underlyingResources = resources[i].getUnderlyingResources();
					for (int j = 0; j < underlyingResources.length; j++) {
						webLibMappings.add(underlyingResources[j].getName());
					}
				}
			}
		} catch (CoreException ce) {
			// swallow
		}
		final Map archiveToPath = new HashMap();
		final IVirtualReference[] webLibs = getWebInfLibModules(component);
		for (int i = 0; i < webLibs.length; i++) {
			IVirtualComponent comp = webLibs[i].getReferencedComponent();
			String name = null;
			if (comp.isBinary()) {
				VirtualArchiveComponent archiveComp = (VirtualArchiveComponent) comp;
				java.io.File diskFile = archiveComp.getUnderlyingDiskFile();
				if (!diskFile.exists()) {
					IFile wbFile = archiveComp.getUnderlyingWorkbenchFile();
					diskFile = new File(wbFile.getLocation().toOSString());
				}
				checkLibName(diskFile.getName(), null, webLibMappings, true);
			} else {
				String archiveName = webLibs[i].getArchiveName();
				if (archiveName != null && archiveName.length() > 0) {
					name = archiveName;
				} else {
					name = comp.getName() + ".jar"; //$NON-NLS-1$
				}
				checkLibName(name, comp.getProject(), webLibMappings, true);
				if (comp instanceof J2EEModuleVirtualComponent) {
					final IVirtualReference[] cpRefs = ((J2EEModuleVirtualComponent) comp).getJavaClasspathReferences();
					for (int j = 0; j < cpRefs.length; j++) {
						final IVirtualReference ref = cpRefs[j];
						if (ref.getReferencedComponent() instanceof VirtualArchiveComponent) {
							final String cpCompName = ref.getArchiveName();
							checkLibName(cpCompName, comp.getProject(), webLibMappings, false);
							IPath cpEntryPath= ClasspathDependencyUtil.getClasspathVirtualReferenceLocation(ref);
							if (cpEntryPath != null) {
								IPath existingPath = (IPath) archiveToPath.get(cpCompName);
								if (existingPath != null && !existingPath.equals(cpEntryPath)) {
									_reporter.addMessage(this, new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_DUPLICATE_CLASSPATH_COMPONENT_URI, new String[]{cpCompName, comp.getProject().getName()}));
								} else {
									archiveToPath.put(cpCompName, cpEntryPath);
								}
							}
						}
					}
				}
			}
		}		
	}
	
	private void checkLibName(final String name, final IProject project, final Set webLibNames, final boolean addName) {
		if (webLibNames.contains(name)) {
			if (project != null) {
				_reporter.addMessage(this, new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_DUPLICATE_WEB_INF_LIB_OTHER_PROJECT, new String[]{name, project.getName()}));
			} else {
				_reporter.addMessage(this, new Message(getBaseName(), IMessage.HIGH_SEVERITY, ERROR_DUPLICATE_WEB_INF_LIB, new String[]{name}));
			}
		} else if (addName) {
			webLibNames.add(name);
		}
	}
	
	private IVirtualReference[] getWebInfLibModules(final IVirtualComponent comp) {
		WebArtifactEdit webArtifactEdit = null;
		try {
			webArtifactEdit = (WebArtifactEdit) ComponentUtilities.getArtifactEditForRead(comp);
			if (webArtifactEdit != null) {
				return webArtifactEdit.getLibModules();
			}
		} finally {
			if (webArtifactEdit != null)
				webArtifactEdit.dispose();
		}
		return new IVirtualReference[0];
	}
	
	/**
	 * Insert the method's description here. Creation date: (10/2/2001 6:49:26 PM)
	 */
	public void validateEARForContextRoot() {

//		IProject project = getWarHelper().getProject();
//		J2EEWebNatureRuntime webNature = J2EEWebNatureRuntime.getRuntime(project);
//		String contextRoot = webNature.getContextRoot();
//
//		if (webNature == null)
//			return;
//
//		EARNatureRuntime earRuntimeNature[] = webNature.getReferencingEARProjects();

//		for (int i = 0; i < earRuntimeNature.length; i++) {
//			// for each Ear Project that contains this web project update the context root.
//			// hold the model and validate the context root & release the model
//			org.eclipse.jst.j2ee.internal.earcreation.EAREditModel editModel = null;
//			try {
//				editModel = earRuntimeNature[i].getEarEditModelForRead(this);
//				if (editModel != null) {
//					Module module = null;
//					if ((module = earRuntimeNature[i].getModule(project)) != null) {
//						String webModcontextRoot = ((WebModule) module).getContextRoot();
//						if (webModcontextRoot != null && !webModcontextRoot.equals(contextRoot)) {
//							String[] params = new String[3];
//							params[0] = project.getName();
//							params[1] = ((WebModule) module).getContextRoot();
//							params[2] = earRuntimeNature[i].getProject().getName();
//							addError(WAR_CATEGORY, ERROR_EAR_INVALID_CONTEXT_ROOT, params);
//						}
//					}
//				}
//			} finally {
//				if (editModel != null) {
//					editModel.releaseAccess(this);
//					editModel = null;
//				}
//			}
//
//		}

	}
	
	/**
	 * Method validateLibModules.
	 * 
	 * 
	 */
	
	//TODO create validation for modules
/*	protected void validateLibModules(J2EEWebNatureRuntime webNature) {
		if (webNature != null) {
			ILibModule[] libModules = webNature.getLibModules();
			IProject project = webNature.getProject();

			for (int i = 0; i < libModules.length; i++) {
				ILibModule lib = libModules[i];
				IProject tProject = lib.getProject();
				if (tProject != null) { // Project could be null if JavaProject is deleted, for
										// example
					if (!tProject.exists() || !tProject.isOpen()) {
						addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_MISSING_WLP_PROJECT, new String[]{tProject.getName()}, webNature.getProject());
					}
				}

				String jarName = lib.getJarName();
				IPath jarPath = webNature.getLibraryFolder().getFullPath().append(jarName);
				if (((Resource) project).findExistingResourceVariant(jarPath) != null)
					addWarning(WAR_CATEGORY, MESSAGE_WAR_VALIDATION_CONFLICTING_WLP_PROJECT, new String[]{jarName}, webNature.getProject());
			}
		}
	}*/	
	
	public ISchedulingRule getSchedulingRule(IValidationContext helper) {
		
		IProject project = ((IWorkbenchContext) helper).getProject();
		IVirtualComponent comp = ComponentCore.createComponent( project );
		IFile webDeploymentDescriptor = null;
		if( comp != null ){
			IVirtualFile vf = comp.getRootFolder().getFile(new Path(J2EEConstants.WEBAPP_DD_URI));
			if( vf!= null ){
				webDeploymentDescriptor = vf.getUnderlyingFile();
			}
		}
		return webDeploymentDescriptor;
	}	

}
