/*******************************************************************************
 * Copyright (c) 2009 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.project;

import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
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.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jst.j2ee.internal.J2EEConstants;
import org.eclipse.jst.j2ee.internal.plugin.J2EEPlugin;
import org.eclipse.jst.j2ee.internal.project.SingleRootStatus;
import org.eclipse.jst.j2ee.internal.project.J2EEProjectUtilities;
import org.eclipse.wst.common.componentcore.internal.ComponentResource;
import org.eclipse.wst.common.componentcore.internal.Property;
import org.eclipse.wst.common.componentcore.internal.StructureEdit;
import org.eclipse.wst.common.componentcore.internal.WorkbenchComponent;
import org.eclipse.wst.common.componentcore.resources.IVirtualComponent;

public class SingleRootUtil {
	
	/** 
	 * Used to return immediately after the first error code is found.
	 */
	public static final int INCLUDE_FIRST_ERROR = 0x08;
	/** 
	 * Used to capture all status codes (error, info, warning).
	 */
	public static final int INCLUDE_ALL = 0x07;
	/** 
	 * Used to capture all error and warning status codes.
	 */
	public static final int INCLUDE_ERRORS_AND_WARNINGS = 0x06;
	/** 
	 * Used to capture all error status codes.
	 */
	public static final int INCLUDE_ERRORS = 0x04;
	
	private static final int WARNINGS = 0x02;
	private static final int INFO = 0x01;
	private static final int NONE = 0x0;
	private static String USE_SINGLE_ROOT_PROPERTY = "useSingleRoot"; //$NON-NLS-1$
	private IVirtualComponent component;
	private IPackageFragmentRoot[] cachedSourceContainers;
	private IContainer[] cachedOutputContainers;
	private boolean isSingleJavaOutputNonSource;
	private MultiStatus wrapperStatus;
	private int INCLUDE_FLAG;
	
	public SingleRootUtil(IVirtualComponent component) {
		this.component = component;
	}
	
	/**
	 * Returns true if this module has a simple structure based on a
	 * single root folder, and false otherwise.
     *
	 * In a single root structure, all files that are contained within the root folder
	 * are part of the module, and are already in the correct module structure. No
	 * module resources exist outside of this single folder.
	 * 
	 * @return true if this module has a single root structure, and
	 *         false otherwise
	 */
	public boolean isSingleRoot() {
		return validateSingleRoot(INCLUDE_FIRST_ERROR).getSeverity() != IStatus.ERROR;
	}

	/**
	 *  Validates whether the component module has a single root structure.
	 *  An IStatus with a severity of OK is returned for a valid single root 
	 *  structure.  A MultiStatus containing children of type ISingleRootStatus
	 *  is returned if any status codes were captured during the validation.
	 *  A MultiStatus with a severity of INFO or WARNING is returned for a valid 
	 *  single root structure containing status codes with no severities of ERROR.
	 *  A MultiStatus with a severity of ERROR means the component does not have a
	 *  valid single root structure.
	 *  
	 * @param flag - indicates the status codes (by severity) to capture 
	 *               during the validation.  
	 *               Valid flags are: INCLUDE_FIRST_ERROR
	 *               				  INCLUDE_ALL
	 *                                INCLUDE_ERRORS_AND_WARNINGS
	 *                                INCLUDE_ERRORS
	 *               
	 * @return IStatus
	 */
	public IStatus validateSingleRoot(int flag) {
		INCLUDE_FLAG = flag;
		isSingleJavaOutputNonSource = false;
		wrapperStatus = null;
		StructureEdit edit = null;
		try {
			edit = StructureEdit.getStructureEditForRead(getProject());
			if (edit == null || edit.getComponent() == null) {
				reportStatus(ISingleRootStatus.NO_COMPONENT_FOUND);
				return getStatus();
			}
		
			WorkbenchComponent wbComp = edit.getComponent();
			List resourceMaps = wbComp.getResources();
			
			// 229650 - check to see if the property 'useSingleRoot' is defined. If it is set and
			// the value of the property is true then it will override the logic checks below
			final List componentProperties = wbComp.getProperties();
			if (componentProperties != null) {
				final Iterator componentPropertiesIterator = componentProperties.iterator();
				while (componentPropertiesIterator.hasNext()) {
					Property wbProperty = (Property) componentPropertiesIterator.next();
					if (USE_SINGLE_ROOT_PROPERTY.equals(wbProperty.getName())) {
						boolean useSingleRoot = Boolean.valueOf(wbProperty.getValue()).booleanValue();
						if (useSingleRoot) {
							return Status.OK_STATUS;
						} else {
							reportStatus(ISingleRootStatus.EXPLICITLY_DISABLED);
							return getStatus();
						}
					}
				}
			}
			
			if (JavaEEProjectUtilities.isEARProject(getProject())) {
				// Always return false for EARs so that members for EAR are always calculated and j2ee modules are filtered out
				reportStatus(ISingleRootStatus.EAR_PROJECT_FOUND);
				return getStatus();
			}
			
			// if there are any linked resources then this is not a single-root module
			if (rootFoldersHaveLinkedContent()) {
				reportStatus(ISingleRootStatus.LINKED_RESOURCES_FOUND); 
				return getStatus();
			}
			
			// If the list is empty, return false
			if (resourceMaps.size() < 1) {
				reportStatus(ISingleRootStatus.NO_RESOURCE_MAPS_FOUND);
				return getStatus();
			}
			
			if (resourceMaps.size() == 1) {
				ComponentResource mapping = (ComponentResource)resourceMaps.get(0); 
				if (mapping.getRuntimePath().equals(Path.ROOT)) {
					IResource sourceResource = getProject().findMember(mapping.getSourcePath());
					if (sourceResource != null && sourceResource.exists()) {
						IPath sourcePath = getProject().getFullPath().append(mapping.getSourcePath());
						if (!isSourceContainer(sourcePath)) {
							return Status.OK_STATUS;
						}
					}
				}
			}
			
			if (JavaEEProjectUtilities.isDynamicWebProject(getProject())) {
				//validate web projects for single root
				validateWebProject(resourceMaps);
			} 
			else if (JavaEEProjectUtilities.isEJBProject(getProject()) || JavaEEProjectUtilities.isJCAProject(getProject())
					|| JavaEEProjectUtilities.isApplicationClientProject(getProject()) || JavaEEProjectUtilities.isUtilityProject(getProject())) {
				
				validateProject(resourceMaps);
			}
			//return the current status
			return getStatus();
		} finally {
			cachedOutputContainers = null;
			cachedSourceContainers = null;
			if (edit != null)
				edit.dispose();
		}
	}

	private void validateProject(List resourceMaps) {	
		// Ensure there are only source folder component resource mappings to the root content folder
		if (isRootResourceMapping(resourceMaps)) {
			IContainer[] javaOutputFolders = getJavaOutputFolders();
			// Verify only one java outputfolder
			if (javaOutputFolders.length==1) {
				// By the time we get here we know: for any folders defined as source in the 
				// .component file that they are also java source folders.
				if (!isSourceContainer(javaOutputFolders[0].getFullPath())) {
					// The single output folder is NOT a source folder so this is single-rooted. Since the
					// output folder (something like classes or bin) is not a source folder, JDT copies all files
					// (including non Java files) to this folder, so every resource needed at runtime is located 
					// in a single directory.
					isSingleJavaOutputNonSource  = true;
					return;
				} 
				// Verify the java output folder is the same as one of the content roots
				IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
				IContainer[] rootFolders = component.getRootFolder().getUnderlyingFolders();
				for (int i=0; i<rootFolders.length; i++) {
					IPath compRootPath = rootFolders[i].getProjectRelativePath();
					if (javaOutputPath.equals(compRootPath))
						return;
				}
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_NOT_A_CONTENT_ROOT);
			}
			else {
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_GREATER_THAN_1);
			}
		}
	}

	private void validateWebProject(List resourceMaps) {
		// Ensure there are only basic component resource mappings -- one for the content folder 
		// and any for src folders mapped to WEB-INF/classes
		if (hasDefaultWebResourceMappings(resourceMaps)) {
			// Verify only one java output folder
			if (getJavaOutputFolders().length==1) {
				// Verify the java output folder is to <content root>/WEB-INF/classes
				IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
				IPath compRootPath = component.getRootFolder().getUnderlyingFolder().getProjectRelativePath();
				if (compRootPath.append(J2EEConstants.WEB_INF_CLASSES).equals(javaOutputPath)) {
					return;
				}
				else {
					reportStatus(ISingleRootStatus.JAVA_OUTPUT_NOT_WEBINF_CLASSES);
				}
			}
			else {
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_GREATER_THAN_1);
			}
		}
	}

	/**
	 * Returns the root folders containing Java output in this module.
	 * 
	 * @return a possibly-empty array of Java output folders
	 */
	public IContainer[] getJavaOutputFolders() {
		if (cachedOutputContainers == null)
			cachedOutputContainers = getJavaOutputFolders(getProject());
		return cachedOutputContainers;
	}
	
	public IContainer[] getJavaOutputFolders(IProject project) {
		if (project == null)
			return new IContainer[0];
		return J2EEProjectUtilities.getOutputContainers(project);
	}
	
	/**
	 * Checks if the path argument is to a source container for the project.
	 * 
	 * @param a workspace relative full path
	 * @return is path a source container?
	 */
	private boolean isSourceContainer(IPath path) {
		IPackageFragmentRoot[] srcContainers = getSourceContainers();
		for (int i = 0; i < srcContainers.length; i++) {
			if (srcContainers[i].getPath().equals(path))
				return true;
		}
		return false;
	}
	
	private IPackageFragmentRoot[] getSourceContainers() {
		if (cachedSourceContainers == null)
			cachedSourceContainers = J2EEProjectUtilities.getSourceContainers(getProject());
		return cachedSourceContainers;
	}
	
	/*
     * This method returns true if the root folders of this component have any linked resources (folder or file);
     * Otherwise false is returned.
     */
    private boolean rootFoldersHaveLinkedContent() {
    	if (this.component != null) {
    		final IContainer[] rootFolders = this.component.getRootFolder().getUnderlyingFolders();
    		for (int i = 0; i < rootFolders.length; i++) {
    			try {
    				boolean hasLinkedContent = this.hasLinkedContent(rootFolders[i]);
    				if (hasLinkedContent) {
    					return true;
    				}
    			}
    			catch (CoreException coreEx) {
    				J2EEPlugin.logError(coreEx);
    			}
    		}
    	}
    	return false;
    }
    
    /*
     * If the resource to check is a file then this method will return true if the file is linked. If the resource to
     * check is a folder then this method will return true if it, any of its sub directories, or any file contained
     * with-in this directory of any of it's sub directories are linked. Otherwise false is returned.
     */
    private boolean hasLinkedContent(final IResource resourceToCheck) throws CoreException {
    	if ((resourceToCheck != null) && resourceToCheck.isAccessible()) {
    		// skip non-accessible files
    		if (resourceToCheck.isLinked()) {
    			return true;
    		}
    		else {
    			switch (resourceToCheck.getType()) {
    				case IResource.FOLDER:
    					// recursively check sub directory contents
    					final IResource[] subDirContents = ((IFolder) resourceToCheck).members();
    					for (int i = 0; i < subDirContents.length; i++) {
    						if (hasLinkedContent(subDirContents[i])) {
    							return true;
    						}
    					}
    					break;
    				case IResource.FILE:
    					return resourceToCheck.isLinked();
    				default:
    					// skip as we only care about files and folders
    					break;
    			}
    		}
    	}
    	return false;
    }
    
    /**
	 * Ensure that any component resource mappings are for source folders and 
	 * that they map to the root content folder
	 * 
	 * @param resourceMaps
	 * @return boolean
	 */
	private boolean isRootResourceMapping(List resourceMaps) {
		for (int i=0; i < resourceMaps.size(); i++) {
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
			// Verify it maps to "/" for the content root
			if (!resourceMap.getRuntimePath().equals(Path.ROOT)) {
				reportStatus(ISingleRootStatus.RUNTIME_PATH_NOT_ROOT, resourceMap);
				if (INCLUDE_FLAG == NONE) return false;
			}
			
			// verify it is also a src container
			IResource sourceResource = getProject().findMember(resourceMap.getSourcePath());
			if (sourceResource != null && sourceResource.exists()){
				IPath sourcePath = getProject().getFullPath().append(resourceMap.getSourcePath());
				if (!isSourceContainer(sourcePath))
					reportStatus(ISingleRootStatus.SOURCE_NOT_JAVA_CONTAINER, resourceMap);
			}
			else {
				reportStatus(ISingleRootStatus.SOURCE_PATH_NOT_FOUND, resourceMap);
			}
			if (INCLUDE_FLAG == NONE) return false;
		}
		return true;
	}
	
	/**
	 * Ensure the default web setup is correct with one resource map and any number of java 
	 * resource maps to WEB-INF/classes
	 * 
	 * @param resourceMaps
	 * @return boolean
	 */
	private boolean hasDefaultWebResourceMappings(List resourceMaps) {
		int rootValidMaps = 0;
	
		IPath webInfClasses = new Path(J2EEConstants.WEB_INF_CLASSES).makeAbsolute();
		for (int i = 0; i < resourceMaps.size(); i++) {
			ComponentResource resourceMap = (ComponentResource) resourceMaps.get(i);
			IPath sourcePath = getProject().getFullPath().append(resourceMap.getSourcePath());

			// Verify if the map is for the content root
			if (resourceMap.getRuntimePath().equals(Path.ROOT)) {
				rootValidMaps++;
			} 
			// Verify if the map is for a java src folder and is mapped to "WEB-INF/classes"
			else if (resourceMap.getRuntimePath().equals(webInfClasses)) {
				if (exists(sourcePath)) {
					if (!isSourceContainer(sourcePath)) {
						reportStatus(ISingleRootStatus.SOURCE_NOT_JAVA_CONTAINER, resourceMap);
					}
				}
				else {
					reportStatus(ISingleRootStatus.SOURCE_PATH_NOT_FOUND, resourceMap);
				}
			}
			else {
				reportStatus(ISingleRootStatus.RUNTIME_PATH_NOT_ROOT_OR_WEBINF_CLASSES, resourceMap);
			}
			if (INCLUDE_FLAG == NONE) return false;
		}
		// Make sure only one of the maps is the content root, and that at least one is for the java folder
		if (rootValidMaps != 1) {
			if (rootValidMaps < 1) {
				reportStatus(ISingleRootStatus.ONE_CONTENT_ROOT_REQUIRED);
			}
			else if (rootValidMaps > 1) {
				reportStatus(ISingleRootStatus.ONLY_1_CONTENT_ROOT_ALLOWED);
			}
		}
		return INCLUDE_FLAG == NONE ? false : true;
	}
	
	/**
	 * Checks if the path argument exists relative to this workspace root.
	 * 
	 * @param a workspace relative full path
	 * @return is path in the workspace?
	 */
	private boolean exists(IPath path) {
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		return workspaceRoot.exists(path);
	}

	private IProject getProject() {
		return component.getProject();
	}

	public boolean isSingleJavaOutputNonSource() {
		return isSingleJavaOutputNonSource;
	}
	
	public void reportStatus(int code) {
		reportStatus(code, null, null);
	}
	
	public void reportStatus(int code, ComponentResource resource) {
		reportStatus(code, resource, null);
	}
	
	public void reportStatus(int code, ComponentResource resource, String message) {
		ISingleRootStatus status = new SingleRootStatus(code, resource, message);
		if (status.getSeverity() == IStatus.ERROR) {
			if ((INCLUDE_FLAG & INCLUDE_FIRST_ERROR) != 0) {
				INCLUDE_FLAG = NONE;
				addStatus(status);
			}
			else if ((INCLUDE_FLAG & INCLUDE_ERRORS) != 0) {
				addStatus(status);
			}
		}
		else if (status.getSeverity() == IStatus.WARNING && (INCLUDE_FLAG & WARNINGS) != 0) {
			addStatus(status);
		}
		else if (status.getSeverity() == IStatus.INFO && (INCLUDE_FLAG & INFO) != 0) { 
			addStatus(status);
		}
	}

	public IStatus getStatus() {
		if (wrapperStatus != null) {
			return wrapperStatus;
		}
		return Status.OK_STATUS;
	}

	private void addStatus(ISingleRootStatus status) {
		if (wrapperStatus == null) {
			wrapperStatus = new MultiStatus(J2EEPlugin.PLUGIN_ID, 0, new IStatus[] { status }, null, null);
		}
		else {
			wrapperStatus.add(status);
		}
	}
	
}
