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 implements IResourceChangeListener
{
    private final static boolean                            ENABLE_TEST_TRACKING
                                                                = false;
    private static long                                     _seqId;
    
    private final CopyOnWriteArrayList<IResource>                   _resources;
    private 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;
    }

    /**
     * @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();
    }

    /**
     * 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);
    }

    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));
            }
        }
    }
}
