package org.eclipse.jst.jsf.common.internal.resource;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.finder.AbstractMatcher.AlwaysMatcher;
import org.eclipse.jst.jsf.common.internal.finder.AbstractMatcher.IMatcher;
import org.eclipse.jst.jsf.common.internal.finder.VisitorMatcher;
import org.eclipse.jst.jsf.common.internal.finder.acceptor.ClasspathEntryJarMatchingAcceptor;
import org.eclipse.jst.jsf.common.internal.finder.acceptor.JarMatchingAcceptor;
import org.eclipse.jst.jsf.common.internal.resource.IClasspathLifecycleListener.ClasspathLifecycleEvent;
import org.eclipse.jst.jsf.common.internal.resource.IJarLocator.JarChangeEvent.Type;

/**
 * A default jar provider that traverses a project and returns all found jars on
 * the classpath that a list of matcher criteria.
 * 
 * @author cbateman
 * 
 */
public class DefaultJarLocator extends AbstractJarLocator
{
    private static final String DISPLAY_NAME = "Default Jar Provider"; //$NON-NLS-1$
    private static final String ID = DefaultJarLocator.class.getCanonicalName();
    private final VisitorMatcher<IProject, ClasspathJarFile, String> _matcher;
    private ClasspathEntryLifecycleListener _classpathEntryListener;
    private final JavaCoreMediator _javaCoreMediator;

    /**
     * @param javaCoreMediator
     */
    public DefaultJarLocator(final JavaCoreMediator javaCoreMediator)
    {
        this(Collections.singletonList(new AlwaysMatcher()), javaCoreMediator);
    }

    /**
     * @param matchers
     * @param javaCoreMediator
     */
    public DefaultJarLocator(final List<? extends IMatcher> matchers,
            final JavaCoreMediator javaCoreMediator)
    {
        super(ID, DISPLAY_NAME);
        _matcher = new VisitorMatcher<IProject, ClasspathJarFile, String>(ID,
                DISPLAY_NAME, new JarMatchingAcceptor(javaCoreMediator),
                matchers);
        _javaCoreMediator = javaCoreMediator;
        _classpathEntryListener = new ClasspathEntryLifecycleListener(
                _javaCoreMediator);
    }

    @Override
    public void start(final IProject project)
    {
        _classpathEntryListener.addLifecycleObject(project);
        _classpathEntryListener.addListener(new IClasspathLifecycleListener()
        {
            public EventResult acceptEvent(final ClasspathLifecycleEvent event)
            {
                final IJavaElement affectedElement = event.getAffectedElement();
                final List<ClasspathJarFile>  affectedJarFiles = new ArrayList<ClasspathJarFile>();
                if (isInteresting(project, affectedElement, event))
                {
                    Type jarEventType = null;
                    switch (event.getType())
                    {
                        case ADDED:
                            jarEventType = Type.JAR_ADDED;
                            affectedJarFiles.addAll(getChangedJars((IPackageFragmentRoot) affectedElement));
                        break;
                        case REMOVED:
                            jarEventType = Type.JAR_REMOVED;
                            affectedJarFiles.addAll(getChangedJars((IPackageFragmentRoot) affectedElement));
                        break;
                        case REMOVED_DELTA:
                            jarEventType = Type.JAR_REMOVED;
                            IResource res = event.getAffectedResource();
                            if (res.getType() == IResource.FILE &&
                                    "jar".equals(res.getFileExtension())) //$NON-NLS-1$
                            {
                                IPath path = res.getLocation();
                                if (path != null)
                                {
                                    affectedJarFiles.add(new ClasspathJarFile(project, path));
                                }
                            }
                        break;
                    }

                    if (jarEventType != null && !affectedJarFiles.isEmpty())
                    {
                        for (final ClasspathJarFile changedJar : affectedJarFiles)
                        {
                            fireChangeEvent(new JarChangeEvent(
                                    DefaultJarLocator.this, jarEventType,
                                    changedJar));
                        }
                    }
                }
                return EventResult.getDefaultEventResult();
            }

            private Collection<? extends ClasspathJarFile> getChangedJars(
                    final IPackageFragmentRoot affectedElement)
            {
                try
                {
                    return new VisitorMatcher<IPackageFragmentRoot, ClasspathJarFile, String>(
                            "", "", new ClasspathEntryJarMatchingAcceptor(project), //$NON-NLS-1$ //$NON-NLS-2$
                            Collections.singletonList(new AlwaysMatcher()))
                            .find(affectedElement);
                } catch (final JavaModelException e)
                {
                    return Collections.EMPTY_LIST;
                } catch (final Exception e)
                {
                    return Collections.EMPTY_LIST;
                }
            }
        });
        super.start(project);
    }

    private boolean isInteresting(final IProject project,
            final IJavaElement affectedElement, final ClasspathLifecycleEvent event)
    {
        return 
            // first filter out events that aren't related to the project we care about.
            (affectedElement != null
                && affectedElement.getJavaProject() != null
                && project
                        .equals(affectedElement.getJavaProject().getProject()))
                // then filter down to only events impacting frag roots
                // or jar file deletions
                && (affectedElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT
                        || (affectedElement.getElementType() == IJavaElement.JAVA_PROJECT
                                    && event.getAffectedResource() != null
                                    && event.getType() == ClasspathLifecycleEvent.Type.REMOVED_DELTA));
    }

    @Override
    public void stop()
    {
        _classpathEntryListener.dispose();
        super.stop();
    }

    @Override
    protected Collection<? extends ClasspathJarFile> doLocate(
            final IProject project)
    {
        try
        {
            return _matcher.find(project);
        } catch (final Exception e)
        {
            JSFCommonPlugin
                    .log(e, "While getting jars for project: " + project); //$NON-NLS-1$
            return getNoResult();
        }
    }
}
