/*******************************************************************************
 * Copyright (c) 2004, 2011 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.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 srcDirs = new ArrayList();
    protected List classDirs = new ArrayList();
    protected List inclusionLists = new ArrayList();
    protected List exclusionLists = new ArrayList();
  
    protected Map variable2valueMap = new LinkedHashMap();
    protected List rawClassPathEntries = new ArrayList();
    protected List rawClassPathEntriesAbsolute = new ArrayList();
 
    private IJavaProject project;
    
    private static Map 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 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 =
            (IClasspathEntry[]) 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 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 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();
            IPath pathVariableValue = file.getWorkspace().getPathVariableManager().getValue(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());
            exclusionLists.add(new ArrayList());                
        }
    }
    
    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());
            exclusionLists.add(new ArrayList());
        }
    }

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

    /**
     * Get runtime classpath items for given project.
     */
    public static List 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 (IClasspathContainer) 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 = (String) 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 (String) 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;
        }

    }
}
