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

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ElementChangedEvent;
import org.eclipse.jdt.core.IElementChangedListener;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaElementDelta;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.internal.resource.IClasspathLifecycleListener.ClasspathLifecycleEvent;

/**
 * @author cbateman
 */
public class ClasspathEntryLifecycleListener
        extends
        AbstractLifecycleListener<IClasspathLifecycleListener.ClasspathLifecycleEvent, IClasspathLifecycleListener, IProject>
        implements IElementChangedListener
{
    private final JavaCoreMediator _mediator;

    /**
     * Initialize an inactive lifecycle listener. A classpath listener will not
     * be installed by this constructor. The object created using this
     * constructor will not fire any events until addClasspathEntry is called at
     * least once to add a target resource
     * 
     * @param mediator
     *            the mediator to use to access JavaCore operations
     * @throws NullPointerException
     *             if mediator is null.
     */
    public ClasspathEntryLifecycleListener(final JavaCoreMediator mediator)
    {
        if (mediator == null)
        {
            throw new NullPointerException(CANNOT_ADD_NULL_RESOURCE);
        }
        _mediator = mediator;
    }

    /**
     * Create a new lifecycle listener for the res
     * 
     * @param entry
     * @param mediator
     *            the workspace to listen to for changes.
     * @throws NullPointerException
     *             if res or workspace is null.
     */
    public ClasspathEntryLifecycleListener(final IProject entry,
            final JavaCoreMediator mediator)
    {
        this(mediator);
        if (entry == null)
        {
            throw new NullPointerException(CANNOT_ADD_NULL_RESOURCE);
        }
        addLifecycleObject(entry);
    }

    public void elementChanged(final ElementChangedEvent event)
    {
        // we are only interested in package fragment roots that are listening
        // for
        if (event.getType() == ElementChangedEvent.POST_CHANGE)
        {
            handlePostChangeEvent(event);
        }
    }

    private void handlePostChangeEvent(final ElementChangedEvent event)
    {
        final IJavaElementDelta delta = event.getDelta();
        new DeltaAcceptor().accept(new DeltaAcceptor.DeltaVisitor()
        {
            public void visit(final IJavaElementDelta visitDelta)
            {
                // we are only interested in package_fragment_root's
                final IJavaElement element = visitDelta.getElement();
                // only interested if a project in our entries list owns the
                // element.
                final IJavaProject javaProject = element.getJavaProject();
                if (javaProject == null
                        || !getLifecycleObjects().contains(
                                javaProject.getProject()))
                {
                    return;
                }
                if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT_ROOT)
                {
                    handlePackageFragmentRoot(visitDelta);
                } else if (element.getElementType() == IJavaElement.JAVA_PROJECT
                        && visitDelta.getResourceDeltas() != null)
                {
                    handleProject(visitDelta);
                }
                // need to test the flags only for package fragment roots
            }

            private void handleProject(final IJavaElementDelta visitDelta)
            {
                for (final IResourceDelta resDelta : visitDelta
                        .getResourceDeltas())
                {
                    try
                    {
                        resDelta.accept(new IResourceDeltaVisitor()
                        {
                            public boolean visit(final IResourceDelta resDelta2)
                                    throws CoreException
                            {
                                if (resDelta2.getKind() == IResourceDelta.REMOVED
                                        && resDelta2.getResource().getType() == IResource.FILE
                                        && "jar".equals(resDelta2.getResource().getFileExtension())) //$NON-NLS-1$
                                {
                                    fireLifecycleEvent(new ClasspathLifecycleEvent(
                                            ClasspathEntryLifecycleListener.this,
                                            visitDelta.getElement(),
                                            ClasspathLifecycleEvent.Type.REMOVED_DELTA,
                                            resDelta2.getResource()));
                                }
                                return true;
                            }
                        });
                    } catch (final CoreException e)
                    {
                        JSFCommonPlugin.log(e);
                    }
                }
            }

            private void handlePackageFragmentRoot(
                    final IJavaElementDelta visitDelta)
            {
                final int flags = visitDelta.getFlags();
                switch (visitDelta.getKind())
                {
                    case IJavaElementDelta.ADDED:
                    {
                        fireLifecycleEvent(new ClasspathLifecycleEvent(
                                ClasspathEntryLifecycleListener.this,
                                visitDelta.getElement(),
                                ClasspathLifecycleEvent.Type.ADDED));
                    }
                    break;
                    case IJavaElementDelta.REMOVED:
                    {
                        fireLifecycleEvent(new ClasspathLifecycleEvent(
                                ClasspathEntryLifecycleListener.this,
                                visitDelta.getElement(),
                                ClasspathLifecycleEvent.Type.REMOVED));
                    }
                    break;
                    case IJavaElementDelta.CHANGED:
                        if ((flags & IJavaElementDelta.F_ADDED_TO_CLASSPATH) != 0)
                        {
                            fireLifecycleEvent(new ClasspathLifecycleEvent(
                                    ClasspathEntryLifecycleListener.this,
                                    visitDelta.getElement(),
                                    ClasspathLifecycleEvent.Type.ADDED));
                        } else if ((flags & IJavaElementDelta.F_REMOVED_FROM_CLASSPATH) != 0)
                        {
                            fireLifecycleEvent(new ClasspathLifecycleEvent(
                                    ClasspathEntryLifecycleListener.this,
                                    visitDelta.getElement(),
                                    ClasspathLifecycleEvent.Type.REMOVED));
                        } else if ((flags & IJavaElementDelta.F_REORDER) != 0)
                        {
                            // TODO: how important is the case of a classpath
                            // reordering?
                        }
                    break;
                }
            }
        }, delta);
    }

    @Override
    protected void addSystemChangeListener()
    {
        _mediator.addElementChangedListener(this);
    }

    @Override
    protected void removeSystemChangeListener()
    {
        _mediator.removeElementChangeListener(this);
    }

    private static class DeltaAcceptor
    {
        public interface DeltaVisitor
        {
            public void visit(final IJavaElementDelta delta);
        }

        public void accept(final DeltaVisitor visitor,
                final IJavaElementDelta delta)
        {
            visitor.visit(delta);
            for (final IJavaElementDelta childDelta : delta
                    .getAffectedChildren())
            {
                accept(visitor, childDelta);
            }
        }
    }
}
