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

import java.util.Collection;
import java.util.Collections;
import java.util.EventObject;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;

/**
 * 
 * @author cbateman
 * @param <EVENTTYPE> 
 * @param <LISTENERTYPE>
 * @param <LIFECYCLEOBJECT>
 * 
 */
public abstract class AbstractLifecycleListener<EVENTTYPE extends EventObject, LISTENERTYPE extends ILifecycleListener<EVENTTYPE>, LIFECYCLEOBJECT>
        extends ImmutableLifecycleListener<LISTENERTYPE>
{
    /**
     * Exception (non-localized) error message thrown when a null object is
     * added.
     */
    protected static final String CANNOT_ADD_NULL_RESOURCE = "Cannot add null object"; //$NON-NLS-1$
    static final boolean TRACE_EVENTS;
    static
    {
        TRACE_EVENTS = Boolean.valueOf(
                Platform.getDebugOption(JSFCommonPlugin.PLUGIN_ID
                        + "/debug/lifecyclelistener")).booleanValue() //$NON-NLS-1$
                || Boolean.valueOf(System.getProperty("org.eclipse.jst.jsf.common/debug/lifecyclelistener")).booleanValue(); //$NON-NLS-1$
    }

    private final CopyOnWriteArrayList<LISTENERTYPE> _listeners = new CopyOnWriteArrayList<LISTENERTYPE>();
    private final CopyOnWriteArrayList<LIFECYCLEOBJECT> _lifecycleObjects = new CopyOnWriteArrayList<LIFECYCLEOBJECT>();
    private final AtomicBoolean _isDisposed = new AtomicBoolean(false);

    /**
     * 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 Throws
     * {@link NullPointerException} if listener == null
     * 
     * @param listener
     */
    @Override
    public void addListener(final LISTENERTYPE listener)
    {
        if (isDisposed())
        {
            throw new IllegalStateException();
        }
        if (listener == null)
        {
            throw new NullPointerException("Cannot pass null listener"); //$NON-NLS-1$
        }
        _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
     */
    @Override
    public void removeListener(final LISTENERTYPE listener)
    {
        if (isDisposed())
        {
            throw new IllegalStateException();
        }
        _listeners.remove(listener);
    }

    /**
     * @param event
     */
    protected void fireLifecycleEvent(final EVENTTYPE event)
    {
        boolean disposeAfter = false;
        if (TRACE_EVENTS)
        {
            System.err.println(event);
        }
        // NOTE: must use iterator through _listeners so that
        // CopyOnWriteArrayList protects us from concurrent modification
        for (final LISTENERTYPE listener : _listeners)
        {
            final EventResult result = listener.acceptEvent(event);
            disposeAfter |= result.getDisposeAfterEvent();
        }
        if (disposeAfter)
        {
            dispose();
        }
    }

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

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

    /**
     * Sub-class disposal specialization.
     */
    protected void doDispose()
    {
        // do nothing by default;  sub-classes should override to provide their
        // own disposal.
    }

    /**
     * @param object
     */
    protected void addLifecycleObject(final LIFECYCLEOBJECT object)
    {
        if (object == null)
        {
            throw new NullPointerException(CANNOT_ADD_NULL_RESOURCE);
        }
        synchronized (_lifecycleObjects)
        {
            // don't add any resources if we've disposed before acquiring the
            // lock
            if (isDisposed())
            {
                return;
            }
            final int preSize = _lifecycleObjects.size();
            if (!_lifecycleObjects.contains(object))
            {
                _lifecycleObjects.add(object);
            }
            // if the size of the array was 0
            // and is now greater, make sure the listener is added
            if (preSize == 0 && _lifecycleObjects.size() > 0)
            {
                addSystemChangeListener();
            }
        }
    }

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

    /**
     * @return an iterable of the lifecycle objects being tracked.
     */
    protected Collection<LIFECYCLEOBJECT> getLifecycleObjects()
    {
        return Collections.unmodifiableCollection(_lifecycleObjects);
    }

    /**
     * Add the system change listener that is used to collect events that will
     * be processed into lifecycle change events.
     */
    protected abstract void addSystemChangeListener();

    /**
     * Remove a system change listener added using addSystemChangeListener
     */
    protected abstract void removeSystemChangeListener();
}
