/*******************************************************************************
 * 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.common.internal.modulecore;

import java.util.Collections;
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.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.jst.common.frameworks.CommonFrameworksPlugin;
import org.eclipse.jst.common.jdt.internal.javalite.JavaLiteUtilities;
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;
import org.eclipse.wst.common.componentcore.resources.IVirtualReference;

public class SingleRootUtil {
	public interface SingleRootCallback {
		public boolean canValidate(IProject project);
		public void validate(SingleRootUtil util, IVirtualComponent vc, IProject project, List resourceMaps);
	}
	
	/** 
	 * 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, warning, info)
	 */
	public static final int INCLUDE_ALL = 0x07;
	/** 
	 * Used to capture all error and warning status codes only.
	 */
	public static final int INCLUDE_ERRORS_AND_WARNINGS = 0x06;
	/** 
	 * Used to capture all error status codes only.
	 */
	public static final int INCLUDE_ERRORS = 0x04;
	
	private static final int WARNINGS = 0x02;
	private static final int INFO = 0x01;
	private static final int CANCEL = 0x0;
	private static final int GET_SINGLE_ROOT_CONTAINER = 0x09;
	private static String USE_SINGLE_ROOT_PROPERTY = "useSingleRoot"; //$NON-NLS-1$
	private IVirtualComponent aComponent;
	private SingleRootCallback callback;
	private List<IContainer> cachedSourceContainers;
	private IContainer[] cachedOutputContainers;
	private MultiStatus wrapperStatus;
	private int VALIDATE_FLAG;
	
	public SingleRootUtil(IVirtualComponent component) {
		this(component, null);
	}

	public SingleRootUtil(IVirtualComponent component, SingleRootCallback callback) {
		this.aComponent = component;
		this.callback = callback;
	}
	

	/**
	 * 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;
	}
	
	/**
	 * Will attempt to return the IContainer that counts as the "single-root".
	 * If this module does not qualify as a "single-root" module, this
	 * method will return null. Otherwise it will return an IContainer
	 * that may be used as the single-root container. 
	 * 
	 * @return IContainer representing single-root container
	 */
	public IContainer getSingleRoot() {
		IStatus status = validateSingleRoot(GET_SINGLE_ROOT_CONTAINER);
		if (status.getSeverity() == IStatus.INFO) {
			IStatus[] children = ((MultiStatus) status).getChildren();
			ISingleRootStatus rootStatus = (ISingleRootStatus) children[0];
			return rootStatus.getSingleRoot();
		}
		return null;	
	}

	/**
	 *  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.  The INLCUDE_ALL flag will also capture the 
	 *               single-root container if a single-root structure was found.
	 *               Valid flags are: 
	 *               				  INCLUDE_ALL
	 *                                INCLUDE_ERRORS_AND_WARNINGS
	 *                                INCLUDE_ERRORS
	 *                                INCLUDE_FIRST_ERROR
	 *               
	 * @return IStatus
	 */
	public IStatus validateSingleRoot(int flag) {
		VALIDATE_FLAG = flag;
		wrapperStatus = null;
		StructureEdit edit = null;
		try {
			edit = StructureEdit.getStructureEditForRead(getProject());
			if (edit == null || edit.getComponent() == null) {
				reportStatus(ISingleRootStatus.NO_COMPONENT_FOUND);
				return getStatus();
			}	
			
			// 229650 - check to see if the property 'useSingleRoot' is defined. 
			Boolean useSingleRoot = getUseSingleRootProperty(edit);
			if (useSingleRoot != null) {
				//check if it was set to false
				if (!useSingleRoot.booleanValue()) {
					reportStatus(ISingleRootStatus.EXPLICITLY_DISABLED);
				}
				else {
					reportStatus(ISingleRootStatus.SINGLE_ROOT_FORCED, aComponent.getRootFolder().getUnderlyingFolder());
				}
				return getStatus();
			}
			
			// if there are any consumed references, this is not single-root
			if (hasConsumableReferences(aComponent)) {
				reportStatus(ISingleRootStatus.CONSUMABLE_REFERENCES_FOUND);
				if (VALIDATE_FLAG == CANCEL)
					return getStatus();
			}
			
			// if there are any linked resources then this is not a single-root module
			if (rootFoldersHaveLinkedContent()) {
				reportStatus(ISingleRootStatus.LINKED_RESOURCES_FOUND);
				if (VALIDATE_FLAG == CANCEL) 
					return getStatus();
			}
			
			List resourceMaps = edit.getComponent().getResources();
			
			// If the list is empty, return false
			if (resourceMaps.size() < 1) {
				reportStatus(ISingleRootStatus.NO_RESOURCE_MAPS_FOUND);
				return getStatus();
			}
			
			if( callback != null && callback.canValidate(getProject())) { 
				callback.validate(this, aComponent, getProject(), resourceMaps);
			} else {
				validateProject(resourceMaps);
			}
			if (VALIDATE_FLAG == CANCEL) 
				return getStatus();

			if (resourceMaps.size() == 1) {
				ComponentResource mapping = (ComponentResource)resourceMaps.get(0); 
				if (isRootMapping(mapping)) {
					IResource sourceResource = getProject().findMember(mapping.getSourcePath());
					if (sourceResource != null && sourceResource.exists()) {
						if (sourceResource instanceof IContainer && !isSourceContainer((IContainer) sourceResource)) {
							reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, (IContainer) sourceResource);
							return getStatus();
						}
					}
				}
			}
			
			return getStatus();
		} finally {
			cachedOutputContainers = null;
			cachedSourceContainers = null;
			if (edit != null)
				edit.dispose();
		}
	}
	
	protected Boolean getUseSingleRootProperty(StructureEdit edit) {
		WorkbenchComponent wbComp = edit.getComponent();
		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())) {
					return Boolean.valueOf(wbProperty.getValue());
				}
			}
		}
		return null;
	}
	
	protected boolean hasConsumableReferences(IVirtualComponent vc) {
		IVirtualReference[] refComponents = vc.getReferences();
    	for (int i = 0; i < refComponents.length; i++) {
    		IVirtualReference reference = refComponents[i];
    		if (reference != null && reference.getDependencyType()==IVirtualReference.DEPENDENCY_TYPE_CONSUMES) {
    			return true;
    		}
    	}
    	return false;
    }

	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])) {
					// 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.
					reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, javaOutputFolders[0]);
					return;
				} 
				// Verify the java output folder is the same as one of the content roots
				IPath javaOutputPath = getJavaOutputFolders()[0].getProjectRelativePath();
				IContainer[] rootFolders = aComponent.getRootFolder().getUnderlyingFolders();
				for (int i=0; i < rootFolders.length; i++) {
					IPath compRootPath = rootFolders[i].getProjectRelativePath();
					if (javaOutputPath.equals(compRootPath)) {
						reportStatus(ISingleRootStatus.SINGLE_ROOT_CONTAINER_FOUND, aComponent.getRootFolder().getUnderlyingFolder());
						return;
					}
				}
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_NOT_A_CONTENT_ROOT);
			}
			else {
				reportStatus(ISingleRootStatus.JAVA_OUTPUT_GREATER_THAN_1);
			}
		}
	}

	public IContainer[] getJavaOutputFolders() {
		if (cachedOutputContainers == null)
			cachedOutputContainers = getJavaOutputFolders(aComponent);
		return cachedOutputContainers;
	}
	
	public static IContainer[] getJavaOutputFolders(IVirtualComponent component) {
		if (component == null)
			return new IContainer[0];
		
		List<IContainer> l = JavaLiteUtilities.getJavaOutputContainers(component);
		return l.toArray(new IContainer[l.size()]);
	}	
	
	/**
	 * 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?
	 */
	public boolean isSourceContainer(IContainer sourceContainer) {
		if (cachedSourceContainers == null) {
			cachedSourceContainers = getSourceContainers(aComponent);
		}
		return cachedSourceContainers.contains(sourceContainer);
	}
	
	public static List<IContainer> getSourceContainers(IVirtualComponent component) {
		if (component == null)
			Collections.emptyList();
		return JavaLiteUtilities.getJavaSourceContainers(component);
	}	
	
	/*
     * 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.aComponent != null) {
    		final IContainer[] rootFolders = this.aComponent.getRootFolder().getUnderlyingFolders();
    		for (int i = 0; i < rootFolders.length; i++) {
    			try {
    				boolean hasLinkedContent = this.hasLinkedContent(rootFolders[i]);
    				if (hasLinkedContent) {
    					return true;
    				}
    			}
    			catch (CoreException coreEx) {
    				CommonFrameworksPlugin.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;
    		}
    		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 (!isRootMapping(resourceMap)) {
				reportStatus(ISingleRootStatus.RUNTIME_PATH_NOT_ROOT, resourceMap.getRuntimePath());
				if (VALIDATE_FLAG == CANCEL) return false;
			}
			
			// verify it is also a src container
			IPath sourcePath = resourceMap.getSourcePath();
			IResource sourceResource = getProject().findMember(sourcePath);
			if (sourceResource != null && sourceResource.exists()) {
				if (sourceResource instanceof IContainer && !isSourceContainer((IContainer) sourceResource)) {
					reportStatus(ISingleRootStatus.SOURCE_NOT_JAVA_CONTAINER, sourcePath);
				}
			}
			else {
				reportStatus(ISingleRootStatus.SOURCE_PATH_NOT_FOUND, sourcePath);
			}
			if (VALIDATE_FLAG == CANCEL) return false;
		}
		return true;
	}
	
	public boolean isRootMapping(ComponentResource map) {
		// Verify it maps to "/" for the content root
		if (map.getRuntimePath().equals(Path.ROOT))
			return true;
		return false;
	}
		
	public IProject getProject() {
		return aComponent.getProject();
	}

	public void reportStatus(int code) {
		reportStatus(code, null, null);
	}
	
	public void reportStatus(int code, IContainer container) {
		reportStatus(code, null, container);
	}
	
	public void reportStatus(int code, IPath path) {
		reportStatus(code, path, null);
	}
	
	public void reportStatus(int code, IPath path, IContainer container) {
		ISingleRootStatus status = new SingleRootStatus(code, path, container);
		if (status.getSeverity() == IStatus.ERROR) {
			if ((VALIDATE_FLAG & INCLUDE_FIRST_ERROR) != 0) {
				VALIDATE_FLAG = CANCEL;
				addStatus(status);
			}
			else if ((VALIDATE_FLAG & INCLUDE_ERRORS) != 0) {
				addStatus(status);
			}
		}
		else if (status.getSeverity() == IStatus.WARNING && (VALIDATE_FLAG & WARNINGS) != 0) {
			addStatus(status);
		}
		else if (status.getSeverity() == IStatus.INFO && (VALIDATE_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(CommonFrameworksPlugin.PLUGIN_ID, 0, new IStatus[] { status }, null, null);
		} else {
			wrapperStatus.add(status);
		}
	}
	
}
