/*******************************************************************************
 * Copyright (c) 2004, 2013 Richard Hoefter 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:
 *     Richard Hoefter (richard.hoefter@web.de) - initial API and implementation, bug 95298, bug 192726, bug 201180
 *     IBM Corporation - nlsing and incorporating into Eclipse, bug 108276
 *******************************************************************************/

package org.eclipse.ant.internal.ui.datatransfer;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.ant.internal.core.IAntCoreConstants;
import org.eclipse.ant.internal.ui.AntUIPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.launching.IRuntimeClasspathEntry;
import org.eclipse.jdt.launching.JavaRuntime;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 * Class to inspect classpath of an Eclipse project.
 */
public class EclipseClasspath {

	protected List<String> srcDirs = new ArrayList<>();
	protected List<String> classDirs = new ArrayList<>();
	protected List<List<String>> inclusionLists = new ArrayList<>();
	protected List<List<String>> exclusionLists = new ArrayList<>();

	protected Map<String, String> variable2valueMap = new LinkedHashMap<>();
	protected List<String> rawClassPathEntries = new ArrayList<>();
	protected List<String> rawClassPathEntriesAbsolute = new ArrayList<>();

	private IJavaProject project;

	private static Map<String, IClasspathContainer> userLibraryCache = new HashMap<>();

	/**
	 * Initialize object with classpath of given project.
	 */
	public EclipseClasspath(IJavaProject project) throws JavaModelException {
		this.project = project;
		handle(project.getRawClasspath());
	}

	/**
	 * Initialize object with runtime classpath of given launch configuration.
	 * 
	 * @param project
	 *            project that contains given launch configuration conf
	 * @param conf
	 *            launch configuration
	 * @param bootstrap
	 *            if true only bootstrap entries are added, if false only non-bootstrap entries are added
	 */
	public EclipseClasspath(IJavaProject project, ILaunchConfiguration conf, boolean bootstrap) throws CoreException {
		this.project = project;

		// convert IRuntimeClasspathEntry to IClasspathEntry
		IRuntimeClasspathEntry[] runtimeEntries;
		// see AbstractJavaLaunchConfigurationDelegate
		runtimeEntries = JavaRuntime.computeUnresolvedRuntimeClasspath(conf);
		List<IClasspathEntry> classpathEntries = new ArrayList<>(runtimeEntries.length);
		for (int i = 0; i < runtimeEntries.length; i++) {
			IRuntimeClasspathEntry entry = runtimeEntries[i];
			if (bootstrap && (entry.getClasspathProperty() == IRuntimeClasspathEntry.BOOTSTRAP_CLASSES) || !bootstrap
					&& (entry.getClasspathProperty() != IRuntimeClasspathEntry.BOOTSTRAP_CLASSES)) {
				// NOTE: See AbstractJavaLaunchConfigurationDelegate.getBootpathExt()
				// for an alternate bootclasspath detection
				if (entry.getClass().getName().equals("org.eclipse.jdt.internal.launching.VariableClasspathEntry")) //$NON-NLS-1$
				{
					IClasspathEntry e = convertVariableClasspathEntry(entry);
					if (e != null) {
						classpathEntries.add(e);
					}
				} else if (entry.getClass().getName().equals("org.eclipse.jdt.internal.launching.DefaultProjectClasspathEntry")) //$NON-NLS-1$
				{
					IClasspathEntry e = JavaCore.newProjectEntry(entry.getPath());
					classpathEntries.add(e);
				} else if (entry.getClasspathEntry() != null) {
					classpathEntries.add(entry.getClasspathEntry());
				}
			} else if (bootstrap && entry.toString().startsWith(JavaRuntime.JRE_CONTAINER)) {
				classpathEntries.add(entry.getClasspathEntry());
			} else if (bootstrap && entry.toString().startsWith(JavaCore.USER_LIBRARY_CONTAINER_ID)) {
				classpathEntries.add(entry.getClasspathEntry());
			}
		}
		IClasspathEntry[] entries = classpathEntries.toArray(new IClasspathEntry[classpathEntries.size()]);

		handle(entries);
	}

	private void handle(IClasspathEntry[] entries) throws JavaModelException {
		for (int i = 0; i < entries.length; i++) {
			handleSources(entries[i]);
			handleVariables(entries[i]);
			handleJars(entries[i]);
			handleLibraries(entries[i]);
			handleProjects(entries[i]);
		}
	}

	private void handleSources(IClasspathEntry entry) throws JavaModelException {
		String projectRoot = ExportUtil.getProjectRoot(project);
		String defaultClassDir = project.getOutputLocation().toString();
		String defaultClassDirAbsolute = ExportUtil.resolve(project.getOutputLocation());

		if (entry.getContentKind() == IPackageFragmentRoot.K_SOURCE && entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {
			// found source path
			IPath srcDirPath = entry.getPath();
			IPath classDirPath = entry.getOutputLocation();
			String srcDir = handleLinkedResource(srcDirPath);
			ExportUtil.removeProjectRoot((srcDirPath != null) ? srcDirPath.toString() : projectRoot, project.getProject());
			String classDir = ExportUtil.removeProjectRoot((classDirPath != null) ? classDirPath.toString() : defaultClassDir, project.getProject());
			srcDirs.add(srcDir);
			classDirs.add(classDir);
			String classDirAbsolute = (classDirPath != null) ? ExportUtil.resolve(classDirPath) : defaultClassDirAbsolute;
			rawClassPathEntries.add(classDir);
			rawClassPathEntriesAbsolute.add(classDirAbsolute);
			IPath[] inclusions = entry.getInclusionPatterns();
			List<String> inclusionList = new ArrayList<>();
			for (int j = 0; j < inclusions.length; j++) {
				if (inclusions[j] != null) {
					inclusionList.add(ExportUtil.removeProjectRoot(inclusions[j].toString(), project.getProject()));
				}
			}
			inclusionLists.add(inclusionList);
			IPath[] exclusions = entry.getExclusionPatterns();
			List<String> exclusionList = new ArrayList<>();
			for (int j = 0; j < exclusions.length; j++) {
				if (exclusions[j] != null) {
					exclusionList.add(ExportUtil.removeProjectRoot(exclusions[j].toString(), project.getProject()));
				}
			}
			exclusionLists.add(exclusionList);
		}
	}

	/**
	 * Check if given source path is a linked resource. Add values to {@link #variable2valueMap} accordingly.
	 * 
	 * @param srcDirPath
	 *            source dir as IPath
	 * @return source directory with reference, e.g. ${MYPATH}/src, if it is no link, orginal source dir is returned
	 */
	private String handleLinkedResource(IPath srcDirPath) {
		String projectRoot = ExportUtil.getProjectRoot(project);
		String srcDir = ExportUtil.removeProjectRoot((srcDirPath != null) ? srcDirPath.toString() : projectRoot, project.getProject());
		if (srcDirPath == null) {
			return srcDir;
		}
		IFile file;
		try {
			file = ResourcesPlugin.getWorkspace().getRoot().getFile(srcDirPath);
		}
		catch (IllegalArgumentException e) {
			return srcDir;
		}
		if (file.isLinked()) {
			String pathVariable = file.getRawLocation().segment(0).toString();
			URI pathVariableValue = file.getWorkspace().getPathVariableManager().getURIValue(pathVariable);
			if (pathVariableValue != null) {
				// path variable was used
				String pathVariableExtension = file.getRawLocation().removeFirstSegments(1).toString(); // Bug 192726
				String relativePath = ExportUtil.getRelativePath(pathVariableValue.toString(), projectRoot);
				variable2valueMap.put(pathVariable + ".pathvariable", relativePath); //$NON-NLS-1$
				variable2valueMap.put(srcDir + ".link", //$NON-NLS-1$
						"${" + pathVariable + ".pathvariable}/" + pathVariableExtension); //$NON-NLS-1$  //$NON-NLS-2$
			} else {
				String relativePath = ExportUtil.getRelativePath(file.getLocation() + IAntCoreConstants.EMPTY_STRING, projectRoot);
				variable2valueMap.put(srcDir + ".link", relativePath); //$NON-NLS-1$
			}
			srcDir = "${" + srcDir + ".link}"; //$NON-NLS-1$ //$NON-NLS-2$
		}
		return srcDir;
	}

	private void handleJars(IClasspathEntry entry) {
		if (entry.getContentKind() == IPackageFragmentRoot.K_BINARY && entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
			String jarFile = entry.getPath().toString();
			StringBuffer jarFileBuffer = new StringBuffer();
			StringBuffer jarFileAbsoluteBuffer = new StringBuffer();
			String jarFileAbsolute = ExportUtil.resolve(entry.getPath());
			if (jarFileAbsolute == null) {
				jarFileAbsolute = jarFile; // jarFile was already absolute
				if (handleSubProjectClassesDirectory(jarFile, jarFileBuffer, jarFileAbsoluteBuffer)) {
					jarFile = jarFileBuffer.toString();
					jarFileAbsolute = jarFileAbsoluteBuffer.toString();
				}
			}
			String jarFileOld = jarFile;
			jarFile = ExportUtil.removeProjectRoot(jarFile, project.getProject());
			if (jarFile.equals(jarFileOld)) {
				if (handleSubProjectClassesDirectory(jarFile, jarFileBuffer, jarFileAbsoluteBuffer)) {
					jarFile = jarFileBuffer.toString();
					jarFileAbsolute = jarFileAbsoluteBuffer.toString();
				}
			}
			rawClassPathEntries.add(jarFile);
			rawClassPathEntriesAbsolute.add(jarFileAbsolute);
		}
	}

	/**
	 * Checks if file is a class directory of a subproject and fills string buffers with resolved values.
	 * 
	 * @param file
	 *            file to check
	 * @param jarFile
	 *            filled with file location with variable reference ${project.location}, which is also added to variable2valueMap
	 * @param jarFileAbsolute
	 *            filled with absolute file location
	 * @return true if file is a classes directory
	 */
	private boolean handleSubProjectClassesDirectory(String file, StringBuffer jarFile, StringBuffer jarFileAbsolute) {
		// class directory of a subproject?
		if (file != null && file.indexOf('/') == 0) {
			int i = file.indexOf('/', 1);
			i = (i != -1) ? i : file.length();
			String subproject = file.substring(1, i);
			IJavaProject javaproject = ExportUtil.getJavaProjectByName(subproject);
			if (javaproject != null) {
				jarFile.setLength(0);
				jarFileAbsolute.setLength(0);
				String location = javaproject.getProject().getName() + ".location"; //$NON-NLS-1$
				jarFileAbsolute.append(ExportUtil.replaceProjectRoot(file, javaproject.getProject(), ExportUtil.getProjectRoot(javaproject)));
				jarFile.append(ExportUtil.replaceProjectRoot(file, javaproject.getProject(), "${" + location + "}")); //$NON-NLS-1$ //$NON-NLS-2$
				String projectRoot = ExportUtil.getProjectRoot(project);
				String relativePath = ExportUtil.getRelativePath(ExportUtil.getProjectRoot(javaproject), projectRoot);
				variable2valueMap.put(location, relativePath);
				return true;
			}
		}
		return false;
	}

	private void handleVariables(IClasspathEntry entry) {
		if (entry.getContentKind() == IPackageFragmentRoot.K_SOURCE && entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
			// found variable
			String e = entry.getPath().toString();
			int index = e.indexOf('/');
			if (index == -1) {
				index = e.indexOf('\\');
			}
			String variable = e;
			String path = IAntCoreConstants.EMPTY_STRING;
			if (index != -1) {
				variable = e.substring(0, index);
				path = e.substring(index);
			}
			IPath value = JavaCore.getClasspathVariable(variable);
			if (value != null) {
				String projectRoot = ExportUtil.getProjectRoot(project);
				String relativePath = ExportUtil.getRelativePath(value.toString(), projectRoot);
				variable2valueMap.put(variable, relativePath);
			} else if (variable2valueMap.get(variable) == null) {
				// only add empty value, if variable is new
				variable2valueMap.put(variable, IAntCoreConstants.EMPTY_STRING);
			}
			rawClassPathEntriesAbsolute.add(value + path);
			rawClassPathEntries.add("${" + variable + "}" + path); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	private void handleLibraries(IClasspathEntry entry) throws JavaModelException {
		if (entry.getContentKind() == IPackageFragmentRoot.K_SOURCE && entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
			// found library
			IClasspathContainer container = JavaCore.getClasspathContainer(entry.getPath(), project);
			if (container == null) {
				// jar missing (project not compile clean)
				return;
			}
			String jar = entry.getPath().toString();
			String refName;
			if (jar.startsWith(JavaRuntime.JRE_CONTAINER)) {
				// JRE System Library
				refName = "${jre.container}"; //$NON-NLS-1$
			} else if (jar.startsWith(JavaCore.USER_LIBRARY_CONTAINER_ID)) {
				// User Library
				String libraryName = container.getDescription();
				refName = "${" + libraryName + ".userclasspath}"; //$NON-NLS-1$ //$NON-NLS-2$
				if (container.getKind() == IClasspathContainer.K_SYSTEM) {
					refName = "${" + libraryName + ".bootclasspath}"; //$NON-NLS-1$ //$NON-NLS-2$
				}
			} else {
				// Library dependencies: e.g. Plug-in Dependencies
				String libraryName = container.getDescription();
				refName = "${" + libraryName + ".libraryclasspath}"; //$NON-NLS-1$ //$NON-NLS-2$
			}
			userLibraryCache.put(refName, container);
			srcDirs.add(refName);
			classDirs.add(refName);
			rawClassPathEntries.add(refName);
			rawClassPathEntriesAbsolute.add(refName);
			inclusionLists.add(new ArrayList<String>());
			exclusionLists.add(new ArrayList<String>());
		}
	}

	private void handleProjects(IClasspathEntry entry) {
		if (entry.getContentKind() == IPackageFragmentRoot.K_SOURCE && entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
			// found required project on build path
			String subProjectRoot = entry.getPath().toString();
			IJavaProject subProject = ExportUtil.getJavaProject(subProjectRoot);
			if (subProject == null) {
				// project was not loaded in workspace
				AntUIPlugin.log("project is not loaded in workspace: " + subProjectRoot, null); //$NON-NLS-1$
				return;
			}
			// only add an indicator that this is a project reference
			String classpathRef = "${" + subProject.getProject().getName() + ".classpath}"; //$NON-NLS-1$ //$NON-NLS-2$
			srcDirs.add(classpathRef);
			classDirs.add(classpathRef);
			rawClassPathEntries.add(classpathRef);
			rawClassPathEntriesAbsolute.add(classpathRef);
			inclusionLists.add(new ArrayList<String>());
			exclusionLists.add(new ArrayList<String>());
		}
	}

	/**
	 * Get runtime classpath items for given project separated with path separator.
	 */
	public static String getClasspath(IJavaProject project) throws CoreException {
		List<String> items = getClasspathList(project);
		return ExportUtil.toString(items, File.pathSeparator);
	}

	/**
	 * Get runtime classpath items for given project.
	 */
	public static List<String> getClasspathList(IJavaProject project) throws CoreException {
		String[] classpath = JavaRuntime.computeDefaultRuntimeClassPath(project);
		return Arrays.asList(classpath);
	}

	/**
	 * Check if given string is a reference.
	 */
	public static boolean isReference(String s) {
		return isProjectReference(s) || isUserLibraryReference(s) || isUserSystemLibraryReference(s) || isLibraryReference(s) || isJreReference(s);
		// NOTE: A linked resource is no reference
	}

	/**
	 * Check if given string is a project reference.
	 */
	public static boolean isProjectReference(String s) {
		return s.startsWith("${") && s.endsWith(".classpath}"); //$NON-NLS-1$ //$NON-NLS-2$ 
	}

	/**
	 * Resolves given project reference to a project.
	 * 
	 * @return <code>null</code> if project is not resolvable
	 */
	public static IJavaProject resolveProjectReference(String s) {
		String name = ExportUtil.removePrefixAndSuffix(s, "${", ".classpath}"); //$NON-NLS-1$ //$NON-NLS-2$
		return ExportUtil.getJavaProjectByName(name);
	}

	/**
	 * Check if given string is a user library reference.
	 */
	public static boolean isUserLibraryReference(String s) {
		return s.startsWith("${") && s.endsWith(".userclasspath}"); //$NON-NLS-1$ //$NON-NLS-2$ 
	}

	/**
	 * Check if given string is a user system library reference. This library is added to the compiler boot classpath.
	 */
	public static boolean isUserSystemLibraryReference(String s) {
		return s.startsWith("${") && s.endsWith(".bootclasspath}"); //$NON-NLS-1$ //$NON-NLS-2$ 
	}

	/**
	 * Check if given string is a library reference. e.g. Plug-in dependencies are library references.
	 * 
	 */
	public static boolean isLibraryReference(String s) {
		return s.startsWith("${") && s.endsWith(".libraryclasspath}"); //$NON-NLS-1$ //$NON-NLS-2$ 
	}

	/**
	 * Check if given string is a JRE reference.
	 */
	public static boolean isJreReference(String s) {
		return s.equals("${jre.container}"); //$NON-NLS-1$
	}

	/**
	 * Resolves given user (system) library or plugin reference to its container.
	 * 
	 * <p>
	 * NOTE: The library can only be resolved if an EclipseClasspath object was created which had a reference to this library. The class holds an
	 * internal cache to circumvent that UserLibraryManager is an internal class.
	 * 
	 * @return null if library is not resolvable
	 */
	public static IClasspathContainer resolveUserLibraryReference(String s) {
		return userLibraryCache.get(s);
	}

	/**
	 * Check if given string is a linked resource.
	 * 
	 */
	public static boolean isLinkedResource(String s) {
		return s.startsWith("${") && s.endsWith(".link}"); //$NON-NLS-1$ //$NON-NLS-2$ 
	}

	/**
	 * Get source folder name of a linked resource.
	 * 
	 * @see #isLinkedResource(String)
	 */
	public static String getLinkedResourceName(String s) {
		return ExportUtil.removePrefixAndSuffix(s, "${", ".link}"); //$NON-NLS-1$ //$NON-NLS-2$ 
	}

	/**
	 * Resolves given linked resource to an absolute file location.
	 */
	public String resolveLinkedResource(String s) {
		String name = ExportUtil.removePrefixAndSuffix(s, "${", "}"); //$NON-NLS-1$ //$NON-NLS-2$
		String value = variable2valueMap.get(name);
		String suffix = ".pathvariable}"; //$NON-NLS-1$
		int i = value.indexOf(suffix);
		if (i != -1) {
			// path variable
			String pathVariable = value.substring(0, i + suffix.length() - 1);
			pathVariable = ExportUtil.removePrefix(pathVariable, "${"); //$NON-NLS-1$
			return variable2valueMap.get(pathVariable) + value.substring(i + suffix.length());
		}
		return value;
	}

	/**
	 * Convert a VariableClasspathEntry to a IClasspathEntry.
	 * 
	 * <p>
	 * This is a workaround as entry.getClasspathEntry() returns null.
	 */
	private IClasspathEntry convertVariableClasspathEntry(IRuntimeClasspathEntry entry) {
		try {
			Document doc = ExportUtil.parseXmlString(entry.getMemento());
			Element element = (Element) doc.getElementsByTagName("memento").item(0); //$NON-NLS-1$
			String variableString = element.getAttribute("variableString"); //$NON-NLS-1$
			ExportUtil.addVariable(variable2valueMap, variableString, ExportUtil.getProjectRoot(project));
			// remove ${...} from string to be conform for handleVariables()
			variableString = ExportUtil.removePrefix(variableString, "${");//$NON-NLS-1$
			int i = variableString.indexOf('}');
			if (i != -1) {
				variableString = variableString.substring(0, i) + variableString.substring(i + 1);
			}
			IPath path = new Path(variableString);
			return JavaCore.newVariableEntry(path, null, null);
		}
		catch (Exception e) {
			AntUIPlugin.log(e);
			return null;
		}

	}
}
