/*******************************************************************************
 * Copyright (c) 2001, 2008 Oracle Corporation 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:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.common.internal.resource;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.jst.jsf.common.internal.ITestTracker;
import org.eclipse.jst.jsf.common.internal.ITestTracker.Event;
import org.eclipse.jst.jsf.common.internal.resource.IResourceLifecycleListener.EventResult;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.EventType;
import org.eclipse.jst.jsf.common.internal.resource.ResourceLifecycleEvent.ReasonType;

/**
 * Listens to resource changes and fires lifecycle events
 * 
 * @author cbateman
 * 
 */
public class LifecycleListener extends ImmutableLifecycleListener implements
        IResourceChangeListener
{
    private final static boolean                           ENABLE_TEST_TRACKING = false;
    private static long                                    _seqId;

    private final CopyOnWriteArrayList<IResource>          _resources;
    final CopyOnWriteArrayList<IResourceLifecycleListener> _listeners;
    private AtomicBoolean                                  _isDisposed          = new AtomicBoolean(
                                                                                        false);
    private ITestTracker                                   _testTracker;                       // ==
                                                                                                // null;
                                                                                                // initialized
                                                                                                // by
                                                                                                // setter
                                                                                                // injection

    /**
     * Initialize an inactive lifecycle listener. A workspace listener will not
     * be installed by this constructor. The object created using this
     * constructor will not fire any events until addResource is called at least
     * once to add a target resource
     */
    public LifecycleListener()
    {
        _resources = new CopyOnWriteArrayList<IResource>();
        _listeners = new CopyOnWriteArrayList<IResourceLifecycleListener>();
    }

    /**
     * Create a new lifecycle listener for the res
     * 
     * @param res
     */
    public LifecycleListener(final IResource res)
    {
        this();
        _resources.add(res);
        ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
    }

    /**
     * @param resources
     */
    public LifecycleListener(final List<IResource> resources)
    {
        this();
        _resources.addAll(resources);
        ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
    }

    /**
     * @param testTracker
     */
    public final void setTestTracker(final ITestTracker testTracker)
    {
        _testTracker = testTracker;
    }

    /**
     * Adds listener to the list of objects registered to receive lifecycle
     * events for this resource. Only adds the listener if it is not already in
     * the list.
     * 
     * Method is thread-safe and may block the caller
     * 
     * Throws {@link IllegalStateException} if isDisposed() == true
     * 
     * @param listener
     */
    public void addListener(final IResourceLifecycleListener listener)
    {
        if (isDisposed())
        {
            throw new IllegalStateException();
        }
        _listeners.addIfAbsent(listener);
    }

    /**
     * Removes listener from the list of registered listeners
     * 
     * Method is thread-safe and may block the caller
     * 
     * Throws {@link IllegalStateException} if isDisposed() == true
     * 
     * @param listener
     */
    public void removeListener(final IResourceLifecycleListener listener)
    {
        if (isDisposed())
        {
            throw new IllegalStateException();
        }
        _listeners.remove(listener);
    }

    /**
     * @param res
     */
    public void addResource(final IResource res)
    {
        synchronized (_resources)
        {
            // don't add any resources if we've disposed before acquiring the
            // lock
            if (isDisposed())
            {
                return;
            }

            final int preSize = _resources.size();
            if (!_resources.contains(res))
            {
                _resources.add(res);
            }

            // if the size of the array was 0
            // and is now greater, make sure the listener is added
            if (preSize == 0 && _resources.size() > 0)
            {
                ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
            }
        }
    }

    /**
     * If there are no longer resources being targeted, the resource change
     * listener will be removed.
     * 
     * @param res
     */
    public void removeResource(final IResource res)
    {
        synchronized (_resources)
        {
            // don't bother with this stuff if we're disposed.
            if (isDisposed())
            {
                return;
            }
            _resources.remove(res);

            // if there are no longer target resources,
            // remove the workspace listener
            if (_resources.size() == 0)
            {
                ResourcesPlugin.getWorkspace().removeResourceChangeListener(
                        this);
            }
        }
    }

    /**
     * Release the resource change listener
     */
    public void dispose()
    {
        if (_isDisposed.compareAndSet(false, true))
        {
            // ensure that add/removeResource don't cause races to add or
            // remove the resource listener
            synchronized (_resources)
            {
                // remove first to minimize the chance that the listener will
                // be triggered during the remainder of dispose
                ResourcesPlugin.getWorkspace().removeResourceChangeListener(
                        this);
                _resources.clear();
            }
        }
    }

    /**
     * @return true if the listener has been disposed
     */
    public boolean isDisposed()
    {
        return _isDisposed.get();
    }

    public void resourceChanged(final IResourceChangeEvent event)
    {
        final long seqId = _seqId++;

        if (ENABLE_TEST_TRACKING && _testTracker != null)
        {
            _testTracker.fireEvent(Event.START_TRACKING, seqId,
                    "trackMethod_resourceChanged");
        }

        assert (!isDisposed());

        switch (event.getType())
        {
            case IResourceChangeEvent.PRE_CLOSE:
            {
                final IProject proj = (IProject) event.getResource();

                // must use iterator to ensure copy on write behaviour
                for (final IResource res : _resources)
                {
                    if (proj == res || proj == res.getProject())
                    {
                        fireLifecycleEvent(new ResourceLifecycleEvent(res,
                                EventType.RESOURCE_INACCESSIBLE,
                                ReasonType.RESOURCE_PROJECT_CLOSED));
                    }
                }
            }
            break;

            case IResourceChangeEvent.PRE_DELETE:
            {
                final IProject proj = (IProject) event.getResource();

                // must use iterator to ensure copy on write behaviour
                for (final IResource res : _resources)
                {
                    // if the resource being tracked is the resource being
                    // deleted,
                    // then fire a resource delete event
                    if (proj == res)
                    {
                        fireLifecycleEvent(new ResourceLifecycleEvent(res,
                                EventType.RESOURCE_INACCESSIBLE,
                                ReasonType.RESOURCE_DELETED));
                    }
                    // if the resource being tracked is a resource in the
                    // project being
                    // deleted, then fire a project deleted event
                    else if (proj == res.getProject())
                    {
                        fireLifecycleEvent(new ResourceLifecycleEvent(res,
                                EventType.RESOURCE_INACCESSIBLE,
                                ReasonType.RESOURCE_PROJECT_DELETED));
                    }
                }
            }
            break;

            case IResourceChangeEvent.POST_CHANGE:
            {
                for (final IResource res : _resources)
                {
                    IResourceDelta delta = event.getDelta();

                    // long seqId2 = _seqId++;
                    // if (ENABLE_TEST_TRACKING && _testTracker != null)
                    // {
                    // _testTracker.fireEvent(Event.START_TRACKING, seqId2,
                    // "testFindMember");
                    // }
                    // only care about post change events to resources
                    // that we are tracking
                    delta = delta.findMember(res.getFullPath());

                    if (delta != null)
                    {
                        visit(delta);
                    }

                    // if (ENABLE_TEST_TRACKING && _testTracker != null)
                    // {
                    // _testTracker.fireEvent(Event.STOP_TRACKING, seqId2,
                    // "testFindMember");
                    // }
                }
            }
            break;

            default:
                // do nothing
                // we only handle these three
        }

        if (ENABLE_TEST_TRACKING && _testTracker != null)
        {
            _testTracker.fireEvent(Event.STOP_TRACKING, seqId,
                    "trackMethod_resourceChanged");
        }
    }

    private void fireLifecycleEvent(final ResourceLifecycleEvent event)
    {
        boolean disposeAfter = false;

        // NOTE: must use iterator through _listeners so that
        // CopyOnWriteArrayList protects us from concurrent modification
        for (final IResourceLifecycleListener listener : _listeners)
        {
            final EventResult result = listener.acceptEvent(event);
            disposeAfter |= result.getDisposeAfterEvent();
        }

        if (disposeAfter)
        {
            dispose();
        }
    }

    private void visit(final IResourceDelta delta)
    {
        assert (!isDisposed());

        final IResource res = delta.getResource();

        // the wkspace root is a special case since even though
        // it is registered as the target resource, we are interested
        // in new projects created in the root
        if (res.getType() == IResource.ROOT)
        {
            handleWorkspaceRoot(delta);
        }

        switch (delta.getKind())
        {
            case IResourceDelta.CHANGED:
            {
                // the contents of the file have changed
                if ((delta.getFlags() & IResourceDelta.CONTENT) != 0)
                {
                    fireLifecycleEvent(new ResourceLifecycleEvent(res,
                            EventType.RESOURCE_CHANGED,
                            ReasonType.RESOURCE_CHANGED_CONTENTS));
                }
            }
            break;
            case IResourceDelta.REMOVED:
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(res,
                        EventType.RESOURCE_INACCESSIBLE,
                        ReasonType.RESOURCE_DELETED));
            }
            break;
        }
    }

    private void handleWorkspaceRoot(final IResourceDelta delta)
    {
        for (final IResourceDelta childDelta : delta
                .getAffectedChildren(IResourceDelta.ADDED))
        {
            final IResource res = childDelta.getResource();
            if ((childDelta.getFlags() & IResourceDelta.OPEN) != 0 &&
            // project was just opened
                    res.getType() == IResource.PROJECT)
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(res,
                        EventType.RESOURCE_ADDED, ReasonType.PROJECT_OPENED));
            }
        }
    }
}
