/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.eclipse.org/org/documents/epl-v10.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.project;

import static com.android.ide.eclipse.adt.AdtConstants.CONTAINER_DEPENDENCIES;

import com.android.SdkConstants;
import com.android.ide.common.sdk.LoadStatus;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AndroidPrintStream;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.build.JarListSanitizer;
import com.android.sdklib.build.JarListSanitizer.DifferentLibException;
import com.android.sdklib.build.JarListSanitizer.Sha1Exception;
import com.android.sdklib.build.RenderScriptProcessor;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathContainer;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;

public class LibraryClasspathContainerInitializer extends BaseClasspathContainerInitializer {

    private final static String ATTR_SRC = "src"; //$NON-NLS-1$
    private final static String ATTR_DOC = "doc"; //$NON-NLS-1$
    private final static String DOT_PROPERTIES = ".properties"; //$NON-NLS-1$

    public LibraryClasspathContainerInitializer() {
    }

    /**
     * Updates the {@link IJavaProject} objects with new library.
     * @param androidProjects the projects to update.
     * @return <code>true</code> if success, <code>false</code> otherwise.
     */
    public static boolean updateProjects(IJavaProject[] androidProjects) {
        try {
            // Allocate a new AndroidClasspathContainer, and associate it to the library
            // container id for each projects.
            int projectCount = androidProjects.length;

            IClasspathContainer[] libraryContainers = new IClasspathContainer[projectCount];
            IClasspathContainer[] dependencyContainers = new IClasspathContainer[projectCount];
            for (int i = 0 ; i < projectCount; i++) {
                libraryContainers[i] = allocateLibraryContainer(androidProjects[i]);
                dependencyContainers[i] = allocateDependencyContainer(androidProjects[i]);
            }

            // give each project their new container in one call.
            JavaCore.setClasspathContainer(
                    new Path(AdtConstants.CONTAINER_PRIVATE_LIBRARIES),
                    androidProjects, libraryContainers, new NullProgressMonitor());

            JavaCore.setClasspathContainer(
                    new Path(AdtConstants.CONTAINER_DEPENDENCIES),
                    androidProjects, dependencyContainers, new NullProgressMonitor());
            return true;
        } catch (JavaModelException e) {
            return false;
        }
    }

    /**
     * Updates the {@link IJavaProject} objects with new library.
     * @param androidProjects the projects to update.
     * @return <code>true</code> if success, <code>false</code> otherwise.
     */
    public static boolean updateProject(List<ProjectState> projects) {
        List<IJavaProject> javaProjectList = new ArrayList<IJavaProject>(projects.size());
        for (ProjectState p : projects) {
            IJavaProject javaProject = JavaCore.create(p.getProject());
            if (javaProject != null) {
                javaProjectList.add(javaProject);
            }
        }

        IJavaProject[] javaProjects = javaProjectList.toArray(
                new IJavaProject[javaProjectList.size()]);

        return updateProjects(javaProjects);
    }

    @Override
    public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
        if (AdtConstants.CONTAINER_PRIVATE_LIBRARIES.equals(containerPath.toString())) {
            IClasspathContainer libraries = allocateLibraryContainer(project);
            if (libraries != null) {
                JavaCore.setClasspathContainer(new Path(AdtConstants.CONTAINER_PRIVATE_LIBRARIES),
                        new IJavaProject[] { project },
                        new IClasspathContainer[] { libraries },
                        new NullProgressMonitor());
            }

        } else if(AdtConstants.CONTAINER_DEPENDENCIES.equals(containerPath.toString())) {
            IClasspathContainer dependencies = allocateDependencyContainer(project);
            if (dependencies != null) {
                JavaCore.setClasspathContainer(new Path(AdtConstants.CONTAINER_DEPENDENCIES),
                        new IJavaProject[] { project },
                        new IClasspathContainer[] { dependencies },
                        new NullProgressMonitor());
            }
        }
    }

    private static IClasspathContainer allocateLibraryContainer(IJavaProject javaProject) {
        final IProject iProject = javaProject.getProject();

        // check if the project has a valid target.
        ProjectState state = Sdk.getProjectState(iProject);
        if (state == null) {
            // getProjectState should already have logged an error. Just bail out.
            return null;
        }

        /*
         * At this point we're going to gather a list of all that need to go in the
         * dependency container.
         * - Library project outputs (direct and indirect)
         * - Java project output (those can be indirectly referenced through library projects
         *   or other other Java projects)
         * - Jar files:
         *    + inside this project's libs/
         *    + inside the library projects' libs/
         *    + inside the referenced Java projects' classpath
         */
        List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();

        // list of java project dependencies and jar files that will be built while
        // going through the library projects.
        Set<File> jarFiles = new HashSet<File>();
        Set<IProject> refProjects = new HashSet<IProject>();

        // process all the libraries

        List<IProject> libProjects = state.getFullLibraryProjects();
        for (IProject libProject : libProjects) {
            // process all of the library project's dependencies
            getDependencyListFromClasspath(libProject, refProjects, jarFiles, true);
        }

        // now process this projects' referenced projects only.
        processReferencedProjects(iProject, refProjects, jarFiles);

        // and the content of its libs folder
        getJarListFromLibsFolder(iProject, jarFiles);

        // now add a classpath entry for each Java project (this is a set so dups are already
        // removed)
        for (IProject p : refProjects) {
            entries.add(JavaCore.newProjectEntry(p.getFullPath(), true /*isExported*/));
        }

        entries.addAll(convertJarsToClasspathEntries(iProject, jarFiles));

        return allocateContainer(javaProject, entries, new Path(AdtConstants.CONTAINER_PRIVATE_LIBRARIES),
                "Android Private Libraries");
    }

    private static List<IClasspathEntry> convertJarsToClasspathEntries(final IProject iProject,
            Set<File> jarFiles) {
        List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>(jarFiles.size());

        // and process the jar files list, but first sanitize it to remove dups.
        JarListSanitizer sanitizer = new JarListSanitizer(
                iProject.getFolder(SdkConstants.FD_OUTPUT).getLocation().toFile(),
                new AndroidPrintStream(iProject, null /*prefix*/,
                        AdtPlugin.getOutStream()));

        String errorMessage = null;

        try {
            List<File> sanitizedList = sanitizer.sanitize(jarFiles);

            for (File jarFile : sanitizedList) {
                if (jarFile instanceof CPEFile) {
                    CPEFile cpeFile = (CPEFile) jarFile;
                    IClasspathEntry e = cpeFile.getClasspathEntry();

                    entries.add(JavaCore.newLibraryEntry(
                            e.getPath(),
                            e.getSourceAttachmentPath(),
                            e.getSourceAttachmentRootPath(),
                            e.getAccessRules(),
                            e.getExtraAttributes(),
                            true /*isExported*/));
                } else {
                    String jarPath = jarFile.getAbsolutePath();

                    IPath sourceAttachmentPath = null;
                    IClasspathAttribute javaDocAttribute = null;

                    File jarProperties = new File(jarPath + DOT_PROPERTIES);
                    if (jarProperties.isFile()) {
                        Properties p = new Properties();
                        InputStream is = null;
                        try {
                            p.load(is = new FileInputStream(jarProperties));

                            String value = p.getProperty(ATTR_SRC);
                            if (value != null) {
                                File srcPath = getFile(jarFile, value);

                                if (srcPath.exists()) {
                                    sourceAttachmentPath = new Path(srcPath.getAbsolutePath());
                                }
                            }

                            value = p.getProperty(ATTR_DOC);
                            if (value != null) {
                                File docPath = getFile(jarFile, value);
                                if (docPath.exists()) {
                                    try {
                                        javaDocAttribute = JavaCore.newClasspathAttribute(
                                                IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME,
                                                docPath.toURI().toURL().toString());
                                    } catch (MalformedURLException e) {
                                        AdtPlugin.log(e, "Failed to process 'doc' attribute for %s",
                                                jarProperties.getAbsolutePath());
                                    }
                                }
                            }

                        } catch (FileNotFoundException e) {
                            // shouldn't happen since we check upfront
                        } catch (IOException e) {
                            AdtPlugin.log(e, "Failed to read %s", jarProperties.getAbsolutePath());
                        } finally {
                            if (is != null) {
                                try {
                                    is.close();
                                } catch (IOException e) {
                                    // ignore
                                }
                            }
                        }
                    }

                    if (javaDocAttribute != null) {
                        entries.add(JavaCore.newLibraryEntry(new Path(jarPath),
                                sourceAttachmentPath, null /*sourceAttachmentRootPath*/,
                                new IAccessRule[0],
                                new IClasspathAttribute[] { javaDocAttribute },
                                true /*isExported*/));
                    } else {
                        entries.add(JavaCore.newLibraryEntry(new Path(jarPath),
                                sourceAttachmentPath, null /*sourceAttachmentRootPath*/,
                                true /*isExported*/));
                    }
                }
            }
        } catch (DifferentLibException e) {
            errorMessage = e.getMessage();
            AdtPlugin.printErrorToConsole(iProject, (Object[]) e.getDetails());
        } catch (Sha1Exception e) {
            errorMessage = e.getMessage();
        }

        processError(iProject, errorMessage, AdtConstants.MARKER_DEPENDENCY,
                true /*outputToConsole*/);

        return entries;
    }

    private static IClasspathContainer allocateDependencyContainer(IJavaProject javaProject) {
        final IProject iProject = javaProject.getProject();
        final List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
        final Set<File> jarFiles = new HashSet<File>();
        final IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

        AdtPlugin plugin = AdtPlugin.getDefault();
        if (plugin == null) { // This is totally weird, but I've seen it happen!
            return null;
        }

        synchronized (Sdk.getLock()) {
            boolean sdkIsLoaded = plugin.getSdkLoadStatus() == LoadStatus.LOADED;

            // check if the project has a valid target.
            final ProjectState state = Sdk.getProjectState(iProject);
            if (state == null) {
                // getProjectState should already have logged an error. Just bail out.
                return null;
            }

            // annotations support for older version of android
            if (state.getTarget() != null && state.getTarget().getVersion().getApiLevel() <= 15) {
                File annotationsJar = new File(Sdk.getCurrent().getSdkOsLocation(),
                        SdkConstants.FD_TOOLS + File.separator + SdkConstants.FD_SUPPORT +
                        File.separator + SdkConstants.FN_ANNOTATIONS_JAR);

                jarFiles.add(annotationsJar);
            }

            if (state.getRenderScriptSupportMode()) {
                if (!sdkIsLoaded) {
                    return null;
                }
                BuildToolInfo buildToolInfo = state.getBuildToolInfo();
                if (buildToolInfo == null) {
                    buildToolInfo = Sdk.getCurrent().getLatestBuildTool();

                    if (buildToolInfo == null) {
                        return null;
                    }
                }

                File renderScriptSupportJar = RenderScriptProcessor.getSupportJar(
                        buildToolInfo.getLocation().getAbsolutePath());

                jarFiles.add(renderScriptSupportJar);
            }

            // process all the libraries

            List<IProject> libProjects = state.getFullLibraryProjects();
            for (IProject libProject : libProjects) {
                // get the project output
                IFolder outputFolder = BaseProjectHelper.getAndroidOutputFolder(libProject);

                if (outputFolder != null) { // can happen when closing/deleting a library)
                    IFile jarIFile = outputFolder.getFile(libProject.getName().toLowerCase() +
                           SdkConstants.DOT_JAR);

                    // get the source folder for the library project
                    List<IPath> srcs = BaseProjectHelper.getSourceClasspaths(libProject);
                    // find the first non-derived source folder.
                    IPath sourceFolder = null;
                    for (IPath src : srcs) {
                        IFolder srcFolder = workspaceRoot.getFolder(src);
                        if (srcFolder.isDerived() == false) {
                            sourceFolder = src;
                            break;
                        }
                    }

                    // we can directly add a CPE for this jar as there's no risk of a duplicate.
                    IClasspathEntry entry = JavaCore.newLibraryEntry(
                            jarIFile.getLocation(),
                            sourceFolder, // source attachment path
                            null,         // default source attachment root path.
                            true /*isExported*/);

                    entries.add(entry);
                }
            }

            entries.addAll(convertJarsToClasspathEntries(iProject, jarFiles));

            return allocateContainer(javaProject, entries, new Path(CONTAINER_DEPENDENCIES),
                    "Android Dependencies");
        }
    }

    private static IClasspathContainer allocateContainer(IJavaProject javaProject,
            List<IClasspathEntry> entries, IPath id, String description) {

        if (AdtPlugin.getDefault() == null) { // This is totally weird, but I've seen it happen!
            return null;
        }

        // First check that the project has a library-type container.
        try {
            IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
            final IClasspathEntry[] oldRawClasspath = rawClasspath;

            boolean foundContainer = false;
            for (IClasspathEntry entry : rawClasspath) {
                // get the entry and kind
                final int kind = entry.getEntryKind();

                if (kind == IClasspathEntry.CPE_CONTAINER) {
                    String path = entry.getPath().toString();
                    String idString = id.toString();
                    if (idString.equals(path)) {
                        foundContainer = true;
                        break;
                    }
                }
            }

            // if there isn't any, add it.
            if (foundContainer == false) {
                // add the android container to the array
                rawClasspath = ProjectHelper.addEntryToClasspath(rawClasspath,
                        JavaCore.newContainerEntry(id, true /*isExported*/));
            }

            // set the new list of entries to the project
            if (rawClasspath != oldRawClasspath) {
                javaProject.setRawClasspath(rawClasspath, new NullProgressMonitor());
            }
        } catch (JavaModelException e) {
            // This really shouldn't happen, but if it does, simply return null (the calling
            // method will fails as well)
            return null;
        }

        return new AndroidClasspathContainer(
                entries.toArray(new IClasspathEntry[entries.size()]),
                id,
                description,
                IClasspathContainer.K_APPLICATION);
    }

    private static File getFile(File root, String value) {
        File file = new File(value);
        if (file.isAbsolute() == false) {
            file = new File(root.getParentFile(), value);
        }

        return file;
    }

    /**
     * Finds all the jar files inside a project's libs folder.
     * @param project
     * @param jarFiles
     */
    private static void getJarListFromLibsFolder(IProject project, Set<File> jarFiles) {
        IFolder libsFolder = project.getFolder(SdkConstants.FD_NATIVE_LIBS);
        if (libsFolder.exists()) {
            try {
                IResource[] members = libsFolder.members();
                for (IResource member : members) {
                    if (member.getType() == IResource.FILE &&
                            SdkConstants.EXT_JAR.equalsIgnoreCase(member.getFileExtension())) {
                        IPath location = member.getLocation();
                        if (location != null) {
                            jarFiles.add(location.toFile());
                        }
                    }
                }
            } catch (CoreException e) {
                // can't get the list? ignore this folder.
            }
        }
    }

    /**
     * Process reference projects from the main projects to add indirect dependencies coming
     * from Java project.
     * @param project the main project
     * @param projects the project list to add to
     * @param jarFiles the jar list to add to.
     */
    private static void processReferencedProjects(IProject project,
            Set<IProject> projects, Set<File> jarFiles) {
        try {
            IProject[] refs = project.getReferencedProjects();
            for (IProject p : refs) {
                // ignore if it's an Android project, or if it's not a Java
                // Project
                if (p.hasNature(JavaCore.NATURE_ID)
                        && p.hasNature(AdtConstants.NATURE_DEFAULT) == false) {

                    // process this project's dependencies
                    getDependencyListFromClasspath(p, projects, jarFiles, true /*includeJarFiles*/);
                }
            }
        } catch (CoreException e) {
            // can't get the referenced projects? ignore
        }
    }

    /**
     * Finds all the dependencies of a given project and add them to a project list and
     * a jar list.
     * Only classpath entries that are exported are added, and only Java project (not Android
     * project) are added.
     *
     * @param project the project to query
     * @param projects the referenced project list to add to
     * @param jarFiles the jar list to add to
     * @param includeJarFiles whether to include jar files or just projects. This is useful when
     *           calling on an Android project (value should be <code>false</code>)
     */
    private static void getDependencyListFromClasspath(IProject project, Set<IProject> projects,
            Set<File> jarFiles, boolean includeJarFiles) {
        IJavaProject javaProject = JavaCore.create(project);
        IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();

        // we could use IJavaProject.getResolvedClasspath directly, but we actually
        // want to see the containers themselves.
        IClasspathEntry[] classpaths = javaProject.readRawClasspath();
        if (classpaths != null) {
            for (IClasspathEntry e : classpaths) {
                // ignore entries that are not exported
                if (!e.getPath().toString().equals(CONTAINER_DEPENDENCIES) && e.isExported()) {
                    processCPE(e, javaProject, wsRoot, projects, jarFiles, includeJarFiles);
                }
            }
        }
    }

    /**
     * Processes a {@link IClasspathEntry} and add it to one of the list if applicable.
     * @param entry the entry to process
     * @param javaProject the {@link IJavaProject} from which this entry came.
     * @param wsRoot the {@link IWorkspaceRoot}
     * @param projects the project list to add to
     * @param jarFiles the jar list to add to
     * @param includeJarFiles whether to include jar files or just projects. This is useful when
     *           calling on an Android project (value should be <code>false</code>)
     */
    private static void processCPE(IClasspathEntry entry, IJavaProject javaProject,
            IWorkspaceRoot wsRoot,
            Set<IProject> projects, Set<File> jarFiles, boolean includeJarFiles) {

        // if this is a classpath variable reference, we resolve it.
        if (entry.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
            entry = JavaCore.getResolvedClasspathEntry(entry);
        }

        if (entry.getEntryKind() == IClasspathEntry.CPE_PROJECT) {
            IProject refProject = wsRoot.getProject(entry.getPath().lastSegment());
            try {
                // ignore if it's an Android project, or if it's not a Java Project
                if (refProject.hasNature(JavaCore.NATURE_ID) &&
                        refProject.hasNature(AdtConstants.NATURE_DEFAULT) == false) {
                    // add this project to the list
                    projects.add(refProject);

                    // also get the dependency from this project.
                    getDependencyListFromClasspath(refProject, projects, jarFiles,
                            true /*includeJarFiles*/);
                }
            } catch (CoreException exception) {
                // can't query the project nature? ignore
            }
        } else if (entry.getEntryKind() == IClasspathEntry.CPE_LIBRARY) {
            if (includeJarFiles) {
                handleClasspathLibrary(entry, wsRoot, jarFiles);
            }
        } else if (entry.getEntryKind() == IClasspathEntry.CPE_CONTAINER) {
            // get the container and its content
            try {
                IClasspathContainer container = JavaCore.getClasspathContainer(
                        entry.getPath(), javaProject);
                // ignore the system and default_system types as they represent
                // libraries that are part of the runtime.
                if (container != null &&
                        container.getKind() == IClasspathContainer.K_APPLICATION) {
                    IClasspathEntry[] entries = container.getClasspathEntries();
                    for (IClasspathEntry cpe : entries) {
                        processCPE(cpe, javaProject, wsRoot, projects, jarFiles, includeJarFiles);
                    }
                }
            } catch (JavaModelException jme) {
                // can't resolve the container? ignore it.
                AdtPlugin.log(jme, "Failed to resolve ClasspathContainer: %s", entry.getPath());
            }
        }
    }

    private static final class CPEFile extends File {
        private static final long serialVersionUID = 1L;

        private final IClasspathEntry mClasspathEntry;

        public CPEFile(String pathname, IClasspathEntry classpathEntry) {
            super(pathname);
            mClasspathEntry = classpathEntry;
        }

        public CPEFile(File file, IClasspathEntry classpathEntry) {
            super(file.getAbsolutePath());
            mClasspathEntry = classpathEntry;
        }

        public IClasspathEntry getClasspathEntry() {
            return mClasspathEntry;
        }
    }

    private static void handleClasspathLibrary(IClasspathEntry e, IWorkspaceRoot wsRoot,
            Set<File> jarFiles) {
        // get the IPath
        IPath path = e.getPath();

        IResource resource = wsRoot.findMember(path);

        if (SdkConstants.EXT_JAR.equalsIgnoreCase(path.getFileExtension())) {
            // case of a jar file (which could be relative to the workspace or a full path)
            if (resource != null && resource.exists() &&
                    resource.getType() == IResource.FILE) {
                jarFiles.add(new CPEFile(resource.getLocation().toFile(), e));
            } else {
                // if the jar path doesn't match a workspace resource,
                // then we get an OSString and check if this links to a valid file.
                String osFullPath = path.toOSString();

                File f = new CPEFile(osFullPath, e);
                if (f.isFile()) {
                    jarFiles.add(f);
                }
            }
        }
    }
}
