/*******************************************************************************
 * Copyright (c) 2001, 2005 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.jem.workbench.utility;
/*
 * $RCSfile: JemProjectUtilities.java,v $ $Revision: 1.11.2.1 $ $Date: 2008/07/07 20:55:49 $
 */

import java.net.URL;
import java.util.*;

import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.jdt.core.*;

import org.eclipse.jem.internal.plugin.JavaEMFNature;
import org.eclipse.jem.java.JavaClass;
import org.eclipse.jem.java.JavaRefFactory;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jem.util.emf.workbench.nature.EMFNature;
import org.eclipse.jem.util.plugin.JEMUtilPlugin;

/**
 * Project Utilities for JEM and Java.
 * 
 * @since 1.1.0
 */
public class JemProjectUtilities extends ProjectUtilities {
	
	private JemProjectUtilities(){
	}
	
	/**
	 * The nature id for JEM Nature.
	 * 
	 * @since 1.1.0
	 */
	public static final String JEM_EMF_NatureID = IJavaEMFNature.NATURE_ID;
	
	/**
	 * Get the EMF nature for JEM for the project. 
	 * @param project
	 * @param addNature <code>true</code> if add the nature to the project if not set. <code>false</code> if don't add nature if not already on project.
	 * @return the EMFNature or <code>null</code> if not found and addNature was <code>false</code> or it was not a java project.
	 * @throws CoreException 
	 * 
	 * @since 1.1.0
	 */
	public static EMFNature getJEM_EMF_Nature(IProject project, boolean addNature) throws CoreException {
		return addNature ? JavaEMFNature.createRuntime(project) : JavaEMFNature.getRuntime(project);
	}

	/**
	 * Get the JavaClass from an IFile.
	 * @param aFile
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public static JavaClass getJavaClass(IFile aFile) {
		if (aFile == null)
			return null;
		IProject project = aFile.getProject();
		List folders = getSourceContainers(project);
		folders.addAll(getLibraryContainers(project));
		IContainer folder = null;
		IPath folderPath, filePath, javaPath;
		filePath = aFile.getProjectRelativePath();
		if (folders != null) {
			for (int i = 0; i < folders.size(); i++) {
				folder = (IContainer) folders.get(i);
				folderPath = folder.getProjectRelativePath();
				int segments = filePath.matchingFirstSegments(folderPath);
				if (segments > 0) {
					javaPath = filePath.removeFirstSegments(segments);
					javaPath = javaPath.removeFileExtension();
					String qualifiedName = javaPath.toString().replace('/', '.');
					return (JavaClass) JavaRefFactory.eINSTANCE.reflectType(qualifiedName, WorkbenchResourceHelperBase.getResourceSet(project));
				}
			}
		}
		return null;
	}
	
	/**
	 * Get source containers for the project.
	 * 
	 * @param p
	 *            project
	 * @return list of source containers.
	 * 
	 * @since 1.0.0
	 */
	public static List getSourceContainers(IProject p) {
		try {
			List sourceContainers = new ArrayList();
			List sourcePaths = getSourcePaths(p);
			if (sourcePaths != null && !sourcePaths.isEmpty()) {
				for (int i = 0; i < sourcePaths.size(); i++) {
					IPath path = (IPath) sourcePaths.get(i);
					if (path.isEmpty())
						sourceContainers.add(p);
					else
						sourceContainers.add(p.getFolder(path));
				}
			}
			return sourceContainers;
		} catch (IllegalArgumentException ex) {
			return Collections.EMPTY_LIST;
		}
	}
	
	protected static List getSourcePaths(IProject p) {
		IJavaProject javaProj = getJavaProject(p);
		if (javaProj == null)
			return null;
		IClasspathEntry[] cp = null;
		try {
			cp = javaProj.getRawClasspath();
		} catch (JavaModelException ex) {
			JEMUtilPlugin.getLogger().logError(ex);
			return null;
		}
		List sourcePaths = new ArrayList();
		for (int i = 0; i < cp.length; i++) {
			if (cp[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
				sourcePaths.add(cp[i].getPath().removeFirstSegments(1));
			}
		}
		return sourcePaths;
	}
	
	/**
	 * Return list of IContainers that are Libraries in the classpath.
	 * 
	 * @param p
	 *            project
	 * @return list of library IContainers.
	 * 
	 * @since 1.0.0
	 */
	public static List getLibraryContainers(IProject p) {
		try {
			List libraryContainers = new ArrayList();
			List libraryPaths = getlibraryPaths(p);
			if (libraryPaths != null && !libraryPaths.isEmpty()) {
				for (int i = 0; i < libraryPaths.size(); i++) {
					IPath path = (IPath) libraryPaths.get(i);
					if (path.isEmpty())
						libraryContainers.add(p);
					else
						libraryContainers.add(p.getFolder(path));
				}
			}
			return libraryContainers;
		} catch (IllegalArgumentException ex) {
			return Collections.EMPTY_LIST;
		}
	}
	
	
	protected static List getlibraryPaths(IProject p) {
		IJavaProject javaProj = getJavaProject(p);
		if (javaProj == null)
			return null;
		IClasspathEntry[] cp = null;
		try {
			cp = javaProj.getRawClasspath();
		} catch (JavaModelException ex) {
			JEMUtilPlugin.getLogger().logError(ex);
			return null;
		}
		List libraryPaths = new ArrayList();
		for (int i = 0; i < cp.length; i++) {
			if (cp[i].getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
				libraryPaths.add(cp[i].getPath().removeFirstSegments(1));
			}
		}
		return libraryPaths;
	}
	
	/**
	 * Get the java project nature for the given project.
	 * 
	 * @param p
	 *            project
	 * @return the java project nature for the project or <code>null</code> if not a java project.
	 * 
	 * @since 1.0.0
	 */
	public static IJavaProject getJavaProject(IProject p) {
		if (p != null)
		{
			try {
				return (IJavaProject) p.getNature(JavaCore.NATURE_ID);
			} catch (CoreException ignore) {
				return null;
			}
		}
		return null;
	}

	/**
	 * Touch classpath. It simply takes the classpath and sets it back in.
	 * 
	 * @param javaProject
	 * @throws JavaModelException
	 * 
	 * @since 1.0.0
	 */
	public static void updateClasspath(IJavaProject javaProject) throws JavaModelException {
		if (javaProject != null)
			javaProject.setRawClasspath(javaProject.getRawClasspath(), new NullProgressMonitor());
	}

	/**
	 * Return the location of the binary output files for the JavaProject.
	 * 
	 * @param p
	 *            project
	 * @return path to binary output folder or <code>null</code> if not java project or other problem.
	 * 
	 * @since 1.0.0
	 */
	public static IPath getJavaProjectOutputLocation(IProject p) {
		try {
			IJavaProject javaProj = getJavaProject(p);
			if (javaProj == null)
				return null;
			if (!javaProj.isOpen())
				javaProj.open(null);
			return javaProj.getOutputLocation();
		} catch (JavaModelException e) {
			return null;
		}
	}

	/**
	 * Get the project's binary output container.
	 * 
	 * @param p
	 *            project
	 * @return project's output container or <code>null</code> if not java project or some other error.
	 * 
	 * @since 1.0.0
	 */
	public static IContainer getJavaProjectOutputContainer(IProject p) {
		IPath path = getJavaProjectOutputLocation(p);
		if (path == null)
			return null;
		if (path.segmentCount() == 1)
			return p;
		return p.getFolder(path.removeFirstSegments(1));
	}

	/**
	 * Get the binary output absolute (local file system) path.
	 * 
	 * @param p
	 *            project
	 * @return project's output path or <code>null</code> if not java project or some other error.
	 * 
	 * @since 1.0.0
	 */
	public static IPath getJavaProjectOutputAbsoluteLocation(IProject p) {
		IContainer container = getJavaProjectOutputContainer(p);
		if (container != null)
			return container.getLocation();
		return null;
	}

	/**
	 * Get the JDT JavaModel.
	 * 
	 * @return JDT's JavaModel
	 * 
	 * @since 1.0.0
	 */
	public static IJavaModel getJavaModel() {
		return JavaCore.create(ResourcesPlugin.getWorkspace().getRoot());
	}

	/**
	 * Get all source package fragment roots.
	 * 
	 * @param javaProj
	 * @return source package fragment roots
	 * @throws JavaModelException
	 * 
	 * @since 1.0.0
	 */
	public static List getSourcePackageFragmentRoots(IJavaProject javaProj) throws JavaModelException {
		List result = new ArrayList();
		IPackageFragmentRoot[] roots = javaProj.getPackageFragmentRoots();
		for (int i = 0; i < roots.length; i++) {
			IPackageFragmentRoot root = roots[i];
			if (root.getKind() == IPackageFragmentRoot.K_SOURCE)
				result.add(root);
		}
		return result;
	}

	/**
	 * Remove the resource from the classpath
	 * 
	 * @param p
	 *            project
	 * @param res
	 *            resource
	 * @throws JavaModelException
	 * 
	 * @since 1.0.0
	 */
	public static void removeFromJavaClassPath(IProject p, IResource res) throws JavaModelException {
		IClasspathEntry entry = JavaCore.newLibraryEntry(res.getFullPath(), null, null);
		removeFromJavaClassPath(p, entry);
	}

	/**
	 * Remove the path from the classpath
	 * 
	 * @param p
	 *            project
	 * @param path
	 *            path to remove
	 * @throws JavaModelException
	 * 
	 * @since 1.0.0
	 */
	public static void removeFromJavaClassPath(IProject p, IPath path) throws JavaModelException {
		org.eclipse.core.resources.IFile f = p.getFile(path);
		removeFromJavaClassPath(p, f);
	}

	/**
	 * Remove the classpath entry from the project's classpath.
	 * 
	 * @param p
	 * @param entry
	 * @throws JavaModelException
	 * 
	 * @since 1.0.0
	 */
	public static void removeFromJavaClassPath(IProject p, IClasspathEntry entry) throws JavaModelException {
		IJavaProject javaProject = null;
		try {
			javaProject = (IJavaProject) p.getNature(JavaCore.NATURE_ID);
		} catch (CoreException ignore) {
		}
		if (javaProject != null) {
			IClasspathEntry[] classpath = javaProject.getRawClasspath();
			javaProject.setRawClasspath(primRemoveFromJavaClassPath(classpath, entry), new NullProgressMonitor());
		}
	}

	/**
	 * Remove the list of entries from the classpath of the project.
	 * 
	 * @param p
	 *            project
	 * @param entries
	 *            list of IClassPathEntry's
	 * @throws JavaModelException
	 * 
	 * @since 1.0.0
	 */
	public static void removeFromJavaClassPath(IProject p, List entries) throws JavaModelException {
		IJavaProject javaProject = null;
		try {
			javaProject = (IJavaProject) p.getNature(JavaCore.NATURE_ID);
		} catch (CoreException ignore) {
		}
		if (javaProject != null) {
			IClasspathEntry[] classpath = javaProject.getRawClasspath();
			javaProject.setRawClasspath(primRemoveFromJavaClassPath(classpath, entries), new NullProgressMonitor());
		}
	}

	protected static IClasspathEntry[] primRemoveFromJavaClassPath(IClasspathEntry[] classpath, IClasspathEntry entry) throws JavaModelException {
		List result = new ArrayList();
		boolean didRemove = false;
		for (int i = 0; i < classpath.length; i++) {
			IClasspathEntry cpEntry = classpath[i];
			if (!entry.getPath().equals(classpath[i].getPath()))
				result.add(cpEntry);
			else
				didRemove = true;
		}
		if (!didRemove)
			return classpath;
		return (IClasspathEntry[]) result.toArray(new IClasspathEntry[result.size()]);
	}

	protected static IClasspathEntry[] primRemoveFromJavaClassPath(IClasspathEntry[] classpath, List entries) throws JavaModelException {
		List arrayList = Arrays.asList(classpath);
		List removeable = new ArrayList(arrayList);
		IClasspathEntry entry;
		boolean didRemove = false;
		int size = entries.size();
		for (int i = 0; i < size; i++) {
			entry = (IClasspathEntry) entries.get(i);
			for (int j = 0; j < classpath.length; j++) {
				IClasspathEntry cpEntry = classpath[j];
				if (entry.getPath().equals(classpath[j].getPath())) {
					if (removeable.remove(cpEntry))
						didRemove = true;
				}
			}
		}
		if (!didRemove)
			return classpath;
		return (IClasspathEntry[]) removeable.toArray(new IClasspathEntry[removeable.size()]);
	}

	/**
	 * Get the classpath as an array or URL's.
	 * 
	 * @param javaProject
	 * @return array of URL's or <code>null</code> if javaProject was <code>null</code>.
	 * 
	 * @since 1.0.0
	 */
	public static URL[] getClasspathAsURLArray(IJavaProject javaProject) {
		if (javaProject == null)
			return null;
		Set visited = new HashSet();
		List urls = new ArrayList(20);
		collectClasspathURLs(javaProject, urls, visited, true);
		URL[] result = new URL[urls.size()];
		urls.toArray(result);
		return result;
	}

	private static void collectClasspathURLs(IJavaProject javaProject, List urls, Set visited, boolean isFirstProject) {
		if (visited.contains(javaProject))
			return;
		visited.add(javaProject);
		IPath outPath = getJavaProjectOutputAbsoluteLocation(javaProject.getProject());
		outPath = outPath.addTrailingSeparator();
		URL out = ProjectUtilities.createFileURL(outPath);
		urls.add(out);
		IClasspathEntry[] entries = null;
		try {
			entries = javaProject.getResolvedClasspath(true);
		} catch (JavaModelException e) {
			return;
		}
		IClasspathEntry entry;
		for (int i = 0; i < entries.length; i++) {
			entry = entries[i];
			switch (entry.getEntryKind()) {
				case IClasspathEntry.CPE_LIBRARY:
				case IClasspathEntry.CPE_CONTAINER:
				case IClasspathEntry.CPE_VARIABLE:
					collectClasspathEntryURL(entry, urls);
					break;
				case IClasspathEntry.CPE_PROJECT: {
					if (isFirstProject || entry.isExported())
						collectClasspathURLs(getJavaProject(entry), urls, visited, false);
					break;
				}
			}
		}
	}

	private static void collectClasspathEntryURL(IClasspathEntry entry, List urls) {
		IPath path = entry.getPath();
		if (null == path.getDevice()) {
			IFile jarFile = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
			if (jarFile.exists()) {
				path = jarFile.getLocation();
			}
		}

		URL url = ProjectUtilities.createFileURL(path);
		if (url != null)
			urls.add(url);
	}


	private static IJavaProject getJavaProject(IClasspathEntry entry) {
		IProject proj = ResourcesPlugin.getWorkspace().getRoot().getProject(entry.getPath().segment(0));
		if (proj != null)
			return getJavaProject(proj);
		return null;
	}

	/**
	 * Is this project a binary project.
	 * <p>
	 * Typically a Java project is considered binary if it does not have a source entry in the classpath.
	 * 
	 * @param project
	 *            Project to test
	 * @return <code>true</code> if project is a binary project.
	 */
	public static boolean isBinaryProject(IProject aProject) {
	
		IJavaProject javaProj = getJavaProject(aProject);
		if (javaProj == null)
			return false;
		IClasspathEntry[] entries = null;
		try {
			entries = javaProj.getRawClasspath();
		} catch (JavaModelException jme) {
			return false;
		}
		for (int i = 0; i < entries.length; i++) {
			IClasspathEntry entry = entries[i];
			if (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE)
				return false;
		}
		return true;
	}

	/**
	 * Append to java class path.
	 * <p>
	 * Append a list of IClasspathEntry's to the build path of the passed project. Updated to remove existing occurrences of the passed entries before
	 * appending.
	 * </p>
	 * 
	 * @param p
	 *            project
	 * @param appendClasspathEntries
	 *            list of entries
	 * @throws JavaModelException
	 * 
	 * @since 1.0.0
	 */
	public static void appendJavaClassPath(IProject p, List appendClasspathEntries) throws JavaModelException {
		IJavaProject javaProject = null;
		try {
			javaProject = (IJavaProject) p.getNature(JavaCore.NATURE_ID);
		} catch (CoreException ignore) {
		}
		if (javaProject != null) {
			IClasspathEntry[] classpath = javaProject.getRawClasspath();
			List newPathList = new ArrayList(classpath.length);
			for (int i = 0; i < classpath.length; i++) {
				IClasspathEntry entry = classpath[i];
				// Skip entries which are in the append list
				if (appendClasspathEntries.indexOf(entry) < 0)
					newPathList.add(entry);
			}
			newPathList.addAll(appendClasspathEntries);
			IClasspathEntry[] newClasspath = (IClasspathEntry[]) newPathList.toArray(new IClasspathEntry[newPathList.size()]);
			javaProject.setRawClasspath(newClasspath, new NullProgressMonitor());
		}
	}

	/**
	 * Append classpath entry.
	 * <p>
	 * Append one IClasspathEntry to the build path of the passed project. If a classpath entry having the same path as the parameter already exists,
	 * then does nothing.
	 * </p>
	 * 
	 * @param p
	 *            Project
	 * @param newEntry
	 *            Entry
	 * @throws JavaModelException
	 * 
	 * @since 1.0.0
	 */
	public static void appendJavaClassPath(IProject p, IClasspathEntry newEntry) throws JavaModelException {
		IJavaProject javaProject = getJavaProject(p);
		if (javaProject == null)
			return;
		IClasspathEntry[] classpath = javaProject.getRawClasspath();
		List newPathList = new ArrayList(classpath.length);
		for (int i = 0; i < classpath.length; i++) {
			IClasspathEntry entry = classpath[i];
			// fix dup class path entry for .JETEmitter project
			// Skip the entry to be added if it already exists
			if (Platform.getOS().equals(Platform.OS_WIN32)) {
				if (!entry.getPath().toString().equalsIgnoreCase(newEntry.getPath().toString()))
					newPathList.add(entry);
				else
					return;
			} else {
				if (!entry.getPath().equals(newEntry.getPath()))
					newPathList.add(entry);
				else
					return;
			}
		}
		newPathList.add(newEntry);
		IClasspathEntry[] newClasspath = (IClasspathEntry[]) newPathList.toArray(new IClasspathEntry[newPathList.size()]);
		javaProject.setRawClasspath(newClasspath, new NullProgressMonitor());
	}

	/**
	 * Return the source path matching the parameter; if the parameter is null, or if the source folder is not on the classpath, return the first
	 * source path on the classpath
	 * 
	 * @param p
	 *            project
	 * @param defaultSourceName
	 *            source folder to find if on classpath, or if <code>null</code> the first folder
	 * @return path searched for or <code>null</code> if not java project or some other problem.
	 * 
	 * @since 1.0.0
	 */
	public static IPath getSourcePathOrFirst(IProject p, String defaultSourceName) {
		IJavaProject javaProj = getJavaProject(p);
		if (javaProj == null)
			return null;
		IClasspathEntry[] cp = null;
		try {
			cp = javaProj.getRawClasspath();
		} catch (JavaModelException ex) {
			JEMUtilPlugin.getLogger().logError(ex);
			return null;
		}
		IClasspathEntry firstSource = null;
		IPath defaultSourcePath = null;
		if (defaultSourceName != null)
			defaultSourcePath = ProjectUtilities.createPath(p, defaultSourceName);
		for (int i = 0; i < cp.length; i++) {
			if (cp[i].getEntryKind() == IClasspathEntry.CPE_SOURCE) {
				if (firstSource == null) {
					firstSource = cp[i];
					if (defaultSourcePath == null)
						break;
				}
				if (cp[i].getPath().equals(defaultSourcePath))
					return defaultSourcePath.removeFirstSegments(1);
			}
		}
		if (firstSource == null)
			return null;
		if (firstSource.getPath().segment(0).equals(p.getName()))
			return firstSource.getPath().removeFirstSegments(1);
		return null;
	}

	/**
	 * Hack to force a reload of the .classpath file
	 * 
	 * @param project
	 *            project to reload
	 * @since 1.0.0
	 */
	public static void forceClasspathReload(IProject project) throws JavaModelException {
		IJavaProject javaProj = getJavaProject(project);
		if (javaProj != null) {
			IClasspathEntry[] entries = javaProj.readRawClasspath();
			if (entries != null) {
				IPath output = javaProj.readOutputLocation();
				if (output != null)
					javaProj.setRawClasspath(entries, output, null);
			}
		}
	}

	/**
	 * Get the paths of all of the local jars in the classpath for the project. It does not recurse into referenced projects.
	 * 
	 * @param proj
	 *            project to search (should be a java project).
	 * @return A list of IPath, where each entry is a project relative path to a JAR contained in the project.
	 */
	public static List getLocalJARPathsFromClasspath(IProject proj) {
		IJavaProject javaProj = getJavaProject(proj);
		if (javaProj == null)
			return null;
		IPath projectPath = proj.getFullPath();
		List result = new ArrayList();
		try {
			IClasspathEntry[] entries = javaProj.getRawClasspath();
			for (int i = 0; i < entries.length; i++) {
				IClasspathEntry entry = entries[i];
				if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
					IPath path = entry.getPath();
					int segments = path.matchingFirstSegments(projectPath);
					if (segments > 0)
						result.add(path.removeFirstSegments(segments));
				}
			}
		} catch (JavaModelException e) {
			JEMUtilPlugin.getLogger().logError(e);
		}
		return result;
	}


	/**
	 * Return the source folder matching the parameter; if the parameter is null, or if the source folder is not on the classpath, return the first
	 * source folder on the classpath
	 * 
	 * @param p
	 *            project
	 * @param defaultSourceName
	 *            source folder to find if on classpath, or if <code>null</code> the first folder
	 * @return container searched for or <code>null</code> if not java project or some other problem.
	 * 
	 * @since 1.0.0
	 */
	public static IContainer getSourceFolderOrFirst(IProject p, String defaultSourceName) {
		try {
			IPath sourcePath = getSourcePathOrFirst(p, defaultSourceName);
			if (sourcePath == null)
				return null;
			else if (sourcePath.isEmpty())
				return p;
			else
				return p.getFolder(sourcePath);
		} catch (IllegalArgumentException ex) {
			return null;
		}
	}

	/**
	 * Returns a list of IFolder that represents each source folder in a java project
	 * 
	 * @deprecated Use {@link #getSourceContainers(IProject)}because the project itself might be a source container
	 * 
	 * @param p
	 *            project
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public static List getSourceFolders(IProject p) {
		try {
			List sourceFolders = new ArrayList();
			List sourcePaths = getSourcePaths(p);
			if (sourcePaths != null && !sourcePaths.isEmpty()) {
				for (int i = 0; i < sourcePaths.size(); i++) {
					IPath path = (IPath) sourcePaths.get(i);
					if (!path.isEmpty())
						sourceFolders.add(p.getFolder(path));
				}
			}
			return sourceFolders;
		} catch (IllegalArgumentException ex) {
			return Collections.EMPTY_LIST;
		}
	}	
}
