/*******************************************************************************
 * 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 org.eclipse.core.resources.IContainer;
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.IWorkspace;
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.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
        AbstractLifecycleListener<ResourceLifecycleEvent, IResourceLifecycleListener, IResource>
        implements IResourceChangeListener
{
    private static boolean ENABLE_TEST_TRACKING = false;
    private static long _seqId;
    private ITestTracker _testTracker; // ==
    final IWorkspace _workspace;

    // 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
     * 
     * @param workspace
     *            the workspace to listen to for changes.
     * @throws NullPointerException
     *             if workspace is null.
     */
    public LifecycleListener(final IWorkspace workspace)
    {
        super();
        if (workspace == null)
        {
            throw new NullPointerException(CANNOT_ADD_NULL_RESOURCE);
        }
        _workspace = workspace;
    }

    /**
     * Create a new lifecycle listener for the res
     * 
     * @param res
     * @param workspace
     *            the workspace to listen to for changes.
     * @throws NullPointerException
     *             if res or workspace is null.
     */
    public LifecycleListener(final IResource res, final IWorkspace workspace)
    {
        this(workspace);
        if (res == null)
        {
            throw new NullPointerException(CANNOT_ADD_NULL_RESOURCE);
        }
        addResource(res);
    }

    /**
     * @param resources
     * @param workspace
     *            the workspace to listen to for changes.
     * @throws NullPointerException
     *             if resources, a member of resources or workspace is null.
     */
    public LifecycleListener(final List<IResource> resources,
            final IWorkspace workspace)
    {
        this(workspace);
        for (final IResource resource : resources)
        {
            if (resource != null)
            {
                addResource(resource);
            } else
            {
                throw new NullPointerException(CANNOT_ADD_NULL_RESOURCE);
            }
        }
    }

    @Override
    protected void addSystemChangeListener()
    {
        _workspace.addResourceChangeListener(this);
    }

    @Override
    protected void removeSystemChangeListener()
    {
        _workspace.removeResourceChangeListener(this);
    }

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

    /**
     * @param newValue
     */
    protected final void setEnableTracing(final boolean newValue)
    {
        ENABLE_TEST_TRACKING = newValue;
    }

    /**
     * @param res
     *            a resource you want to receive events for. MUST NOT BE NULL.
     * @throw {@link NullPointerException} if res is null
     */
    public void addResource(final IResource res)
    {
        addLifecycleObject(res);
    }

    public void resourceChanged(final IResourceChangeEvent event)
    {
        final long seqId = _seqId++;
        if (_testTracker != null && ENABLE_TEST_TRACKING)
        {
            _testTracker.fireEvent(Event.START_TRACKING, seqId,
                    "trackMethod_resourceChanged"); //$NON-NLS-1$
        }
        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 : getLifecycleObjects())
                {
                    if (proj == res || proj == res.getProject())
                    {
                        fireLifecycleEvent(new ResourceLifecycleEvent(this,
                                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 : getLifecycleObjects())
                {
                    // if the resource being tracked is the resource being
                    // deleted,
                    // then fire a resource delete event
                    if (proj == res)
                    {
                        fireLifecycleEvent(new ResourceLifecycleEvent(this,
                                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(this,
                                res, EventType.RESOURCE_INACCESSIBLE,
                                ReasonType.RESOURCE_PROJECT_DELETED));
                    }
                }
            }
            break;
            case IResourceChangeEvent.POST_CHANGE:
            {
                for (final IResource res : getLifecycleObjects())
                {
                    IResourceDelta delta = event.getDelta();
                    // only care about post change events to resources
                    // that we are tracking
                    if (delta != null)
                    {
                        delta = delta.findMember(res.getFullPath());
                        if (delta != null)
                        {
                            visit(delta);
                        }
                    }
                }
            }
            break;
            default:
                // do nothing
                // we only handle these three
        }
        if (ENABLE_TEST_TRACKING && _testTracker != null)
        {
            _testTracker.fireEvent(Event.STOP_TRACKING, seqId,
                    "trackMethod_resourceChanged"); //$NON-NLS-1$
        }
    }

    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);
        } else if (res instanceof IContainer)
        {
            handleContainer(delta, res);
        } else
        {
            handleFile(delta, res);
        }
    }

    private void handleContainer(final IResourceDelta delta, IResource container)
    {
        handleChange(delta, container, container);
        for (final IResourceDelta childDelta : delta.getAffectedChildren())
        {
            if (childDelta.getResource().getType() == IResource.FILE
                    || childDelta.getResource().getType() == IResource.FOLDER)
            {
                handleChange(childDelta, childDelta.getResource(), container);
            }
        }
    }

    private void handleFile(final IResourceDelta delta, final IResource res)
    {
        switch (delta.getKind())
        {
            case IResourceDelta.ADDED:
            case IResourceDelta.REMOVED:
            {
                handleChange(delta, res, res);
            }
            break;
            case IResourceDelta.CHANGED:
            {
                // the contents of the file have changed
                if ((delta.getFlags() & IResourceDelta.CONTENT) != 0)
                {
                    fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                            EventType.RESOURCE_CHANGED,
                            ReasonType.RESOURCE_CHANGED_CONTENTS));
                }
            }
            break;
        }
    }

    private void handleChange(final IResourceDelta delta, final IResource res,
            final IResource interestedResource)
    {
        switch (delta.getKind())
        {
            case IResourceDelta.ADDED:
            {
                handleAdd(delta, res, interestedResource);
            }
            break;
            case IResourceDelta.REMOVED:
            {
                handleRemove(delta, res, interestedResource);
            }
            break;
        }
    }

    private void handleRemove(final IResourceDelta delta, final IResource res,
            final IResource interestedResource)
    {
        if ((delta.getFlags() & IResourceDelta.MOVED_TO) != 0)
        {
            if (res.equals(interestedResource))
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                        EventType.RESOURCE_INACCESSIBLE,
                        ReasonType.RESOURCE_MOVED));
            } else if (res.getParent().equals(interestedResource))
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                        EventType.RESOURCE_INACCESSIBLE,
                        ReasonType.RESOURCE_MOVED_CONTAINER));
            }
        } else
        {
            if (res.equals(interestedResource))
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                        EventType.RESOURCE_INACCESSIBLE,
                        ReasonType.RESOURCE_DELETED));
            } else if (res.getParent().equals(interestedResource))
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                        EventType.RESOURCE_INACCESSIBLE,
                        ReasonType.RESOURCE_DELETED_FROM_CONTAINER));
            }
        }
    }

    private void handleAdd(final IResourceDelta delta, final IResource res,
            final IResource interestedResource)
    {
        if ((delta.getFlags() & IResourceDelta.MOVED_FROM) != 0)
        {
            if (res.equals(interestedResource))
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                        EventType.RESOURCE_ADDED, ReasonType.RESOURCE_MOVED));
            } else if (res.getParent().equals(interestedResource))
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                        EventType.RESOURCE_ADDED,
                        ReasonType.RESOURCE_MOVED_CONTAINER));
            }
        } else
        {
            if (res.equals(interestedResource))
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                        EventType.RESOURCE_ADDED, ReasonType.RESOURCE_ADDED));
            } else if (res.getParent().equals(interestedResource))
            {
                fireLifecycleEvent(new ResourceLifecycleEvent(this, res,
                        EventType.RESOURCE_ADDED,
                        ReasonType.RESOURCE_ADDED_TO_CONTAINER));
            }
        }
    }

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