/*******************************************************************************
 * 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.2.1 $ $Date: 2009/10/22 19:08:13 $
 */

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()) {
			// workspace resource - is the IPath a file, folder, or a class folder whose location is the project root?
			if(path.segmentCount() == 1) {
				// It's a class folder whose location is the project root
				path = ResourcesPlugin.getWorkspace().getRoot().getProject(path.lastSegment()).getLocation();
			}
			else {
				// It's a file or folder - capture it's absolute location
				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;
		}
	}	
}
