/*******************************************************************************
 * Copyright (c) 2011 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.wst.jsdt.web.core.internal;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

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.Path;
import org.eclipse.wst.common.componentcore.ComponentCore;
import org.eclipse.wst.common.componentcore.ModuleCoreNature;
import org.eclipse.wst.common.componentcore.resources.IVirtualFile;
import org.eclipse.wst.jsdt.core.IIncludePathAttribute;
import org.eclipse.wst.jsdt.core.IIncludePathEntry;
import org.eclipse.wst.jsdt.core.JavaScriptCore;
import org.eclipse.wst.jsdt.internal.core.ClasspathEntry;
import org.eclipse.wst.jsdt.internal.core.JavaProject;
import org.eclipse.wst.jsdt.internal.core.util.Messages;
import org.eclipse.wst.jsdt.web.core.internal.project.ModuleSourcePathProvider;
import org.eclipse.wst.sse.core.indexing.AbstractIndexManager;

/**
 * <p>This is an implementation of the {@link AbstractIndexManager} for the JavaScript Web core plugin.</p>
 * 
 * <p>Current Uses:
 * <ul>
 * <li>listen for .project changes so that JavaScript class paths can be updated
 * if the module core nature is added to a project</li>
 * </ul></p>
 * 
 * <p><b>NOTE:</b> If any other file resource change listening needs to take place in the future
 * in this plugin it should be done here.</p>
 */
public class JSWebResourceEventManager extends AbstractIndexManager {
	/** the singleton instance of the {@link JSWebResourceEventManager} */
	private static JSWebResourceEventManager INSTANCE;
	
	/** the name of the ".project" file where natures are stored */
	private static final String DOT_PROJECT_FILE_NAME = ".project"; //$NON-NLS-1$
	
	/** the location to store state */
	private IPath fWorkingLocation;
	
	/**
	 * <p>Private constructor for the resource event manager</p>
	 */
	private JSWebResourceEventManager() {
		super(Messages.build_analyzingDeltas, Messages.build_analyzingDeltas,
				JsCoreMessages.model_initialization, Messages.manager_filesToIndex);
	}
	
	/**
	 * @return the singleton instance of the {@link JSWebResourceEventManager}
	 */
	public static JSWebResourceEventManager getDefault() {
		return INSTANCE != null ? INSTANCE : (INSTANCE = new JSWebResourceEventManager());
	}

	/**
	 * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#isResourceToIndex(int, org.eclipse.core.runtime.IPath)
	 */
	protected boolean isResourceToIndex(int type, IPath path) {
		return 
			type == IResource.ROOT ||
			type == IResource.PROJECT || 
			(type == IResource.FILE && DOT_PROJECT_FILE_NAME.equals(path.lastSegment()));
	}

	/**
	 * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#performAction(byte, byte, org.eclipse.core.resources.IResource, org.eclipse.core.runtime.IPath)
	 */
	protected void performAction(byte source, byte action, IResource resource,
			IPath movePath) {
		
		switch(action) {
			case(AbstractIndexManager.ACTION_ADD): {
				if(resource.getName().equals(DOT_PROJECT_FILE_NAME)) {
					updateClassPathEntries(resource.getProject());
				}
				break;
			}
		}

	}

	/**
	 * @see org.eclipse.wst.sse.core.indexing.AbstractIndexManager#getWorkingLocation()
	 */
	protected IPath getWorkingLocation() {
		if(this.fWorkingLocation == null) {
			//create path to working area
    		IPath workingLocation =
    			JsCorePlugin.getDefault().getStateLocation().append("resourceEventManager"); //$NON-NLS-1$

            // ensure that it exists on disk
            File folder = new File(workingLocation.toOSString());
    		if (!folder.isDirectory()) {
    			try {
    				folder.mkdir();
    			}
    			catch (SecurityException e) {
    				Logger.logException(this.getName() +
    						": Error while creating state location: " + folder + //$NON-NLS-1$
    						" This renders the index manager irrevocably broken for this workspace session", //$NON-NLS-1$
    						e);
    			}
    		}
    		
    		this.fWorkingLocation = workingLocation;
    	}
    	
        return this.fWorkingLocation;
	}
	
	/**
	 * <p>Updates the JavaScript class path entries for the given project if
	 * both the Module core and JavaScript natures are installed on that project.</p>
	 *
	 * @param project {@link IProject} to update the JavaScript class path entries for
	 */
	private static void updateClassPathEntries(IProject project) {
		try {
			/*
			 * if a JS project with Module Core nature, check if include path
			 * needs to be updated
			 */
			if (project.hasNature(JavaScriptCore.NATURE_ID) && ModuleCoreNature.isFlexibleProject(project)) {
				JavaProject jsProject = (JavaProject) JavaScriptCore.create(project);

				IIncludePathEntry[] oldEntries = jsProject.getRawIncludepath();
				List updatedEntries = new ArrayList();
				boolean updateIncludePath = false;

				for (int oldEntry = 0; oldEntry < oldEntries.length; ++oldEntry) {
					IIncludePathAttribute[] entryAttributes = oldEntries[oldEntry].getExtraAttributes();

					boolean isProvidedEntry = false;
					for (int attribute = 0; attribute < entryAttributes.length; ++attribute) {
						isProvidedEntry = entryAttributes[attribute].getName().equals(ModuleSourcePathProvider.PROVIDER_ATTRIBUTE_KEY_NAME) && entryAttributes[attribute].getValue().equals(ModuleSourcePathProvider.PROVIDER_ATTRIBUTE_KEY_VALUE);
						updateIncludePath |= isProvidedEntry;
						if (isProvidedEntry) {
							/*
							 * create updated exclusion paths that are not
							 * relative to the parent entry
							 */
							IPath[] nonRelativeExclusionPaths = oldEntries[oldEntry].getExclusionPatterns();
							for (int i = 0; i < nonRelativeExclusionPaths.length; ++i) {
								nonRelativeExclusionPaths[i] = oldEntries[oldEntry].getPath().append(nonRelativeExclusionPaths[i]);
							}

							/*
							 * create updated inclusion paths that are not
							 * relative to the parent entry
							 */
							IPath[] nonRelativeInclusionPaths = oldEntries[oldEntry].getInclusionPatterns();
							for (int i = 0; i < nonRelativeInclusionPaths.length; ++i) {
								nonRelativeInclusionPaths[i] = oldEntries[oldEntry].getPath().append(nonRelativeInclusionPaths[i]);
							}

							IResource[] roots = getRoots(project);
							IIncludePathEntry[] resolvedEntries = jsProject.getResolvedClasspath();
							for (int root = 0; root < roots.length; ++root) {
								IPath rootPath = roots[root].getFullPath();
								
								// make sure we do not create a source entry that conflicts with an existing library
								boolean foundMatch = false;
								for(int k = 0; k < resolvedEntries.length; k++) {
									if(resolvedEntries[k].getPath().equals(rootPath)) {
										foundMatch = true;
										break;
									}
								}
								if(foundMatch)
									continue;

								/*
								 * find matching pre-existing exclusion
								 * patterns
								 */
								List exclusionPatterns = new ArrayList();
								for (int i = 0; i < nonRelativeExclusionPaths.length; ++i) {
									IPath parentRelativeExclusionPattern = PathUtils.makePatternRelativeToParent(nonRelativeExclusionPaths[i], rootPath);
									if (parentRelativeExclusionPattern != null) {
										exclusionPatterns.add(parentRelativeExclusionPattern);
									}
								}

								/*
								 * find matching pre-existing inclusion
								 * patterns
								 */
								List inclusionPatterns = new ArrayList();
								for (int i = 0; i < nonRelativeInclusionPaths.length; ++i) {
									IPath parentRelativeInclusionPattern = PathUtils.makePatternRelativeToParent(nonRelativeInclusionPaths[i], rootPath);
									if (parentRelativeInclusionPattern != null) {
										inclusionPatterns.add(parentRelativeInclusionPattern);
									}
								}

								// create new inclusion/exclusion rules
								IPath[] exclusionPaths = exclusionPatterns.isEmpty() ? ClasspathEntry.EXCLUDE_NONE : (IPath[]) exclusionPatterns.toArray(new IPath[exclusionPatterns.size()]);
								IPath[] inclusionPaths = inclusionPatterns.isEmpty() ? ClasspathEntry.INCLUDE_ALL : (IPath[]) inclusionPatterns.toArray(new IPath[inclusionPatterns.size()]);

								IIncludePathEntry newEntry = JavaScriptCore.newSourceEntry(rootPath, inclusionPaths, exclusionPaths, null);
								updatedEntries.add(newEntry);
							}
						}
					}
					if (!isProvidedEntry) {
						updatedEntries.add(oldEntries[oldEntry]);
					}
				}

				/*
				 * if found that a default source path was added, replace with
				 * module core determined path
				 */
				if (updateIncludePath) {
					// commit the updated include path
					jsProject.setRawIncludepath((IIncludePathEntry[]) updatedEntries.toArray(new IIncludePathEntry[updatedEntries.size()]), jsProject.getOutputLocation(), null);
				}
			}
		}
		catch (CoreException e) {
			Logger.logException("Error while updating JavaScript includepath", e); //$NON-NLS-1$
		}
	}
	
	/**
	 * <p>Uses module core to get the roots of the given project.</p>
	 *
	 * @param project find the module core roots for this {@link IProject}
	 * @return the module core roots for the given {@link IProject
	 */
	private static IResource[] getRoots(IProject project) {
		IVirtualFile root = ComponentCore.createFile(project, Path.ROOT);
		IResource[] underlyingResources = root.getUnderlyingResources();
		if (underlyingResources == null || underlyingResources.length == 0) {
			underlyingResources = new IResource[]{root.getUnderlyingResource()};
		}
		
		return underlyingResources;
	}
}