/*******************************************************************************
 * Copyright (c) 2009, 2012 SAP AG 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:
 *     SAP AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.ocl.examples.eventmanager.framework;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.LinkedList;
import java.util.WeakHashMap;
import java.util.logging.Logger;

import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.ocl.examples.eventmanager.EventFilter;
import org.eclipse.ocl.examples.eventmanager.EventManager;
import org.eclipse.ocl.examples.eventmanager.EventManagerFactory;
import org.eclipse.ocl.examples.eventmanager.filters.AbstractEventFilter;


/**
 * A scalable implementation of the {@link EventManager} interface, using hash tables to quickly dispatch
 * incoming {@link Notification}s to the sets of registered {@link Adapter event listeners}. Uses a single
 * {@link EContentAdapter} to listen to all changes in those {@link ResourceSet}s for which it is responsible.
 * 
 * @author Daniel Vocke (D044825)
 * @author Axel Uhl (D043530)
 */

public class EventManagerTableBased implements EventManager {
    private Logger logger = Logger.getLogger(EventManagerTableBased.class.getName());
    
    private boolean active = true;
    
    /**
     * the EventAdapter instance for the EventManager
     */
    private final EventAdapter adapter = new EventAdapter(this);

    /**
     * Toogle the {@link EventManager} off, on given <code>false</code> and no {@link Notification}s will be delivered
     * @param doFireEventsValue <code>false</code> to disable {@link Notification}delivery, <code>true</code> to enable
     */
    public void setFireEvents(boolean doFireEventsValue) {
        doFireEvents = doFireEventsValue;
    }

    private boolean doFireEvents = true;

    /**
     * listeners are not notified directly. The notification process is done by the appropriate AdapterCapsule. This Map provides
     * the associated AdapterCapsule for a Listener. For each type of Listener there is a separate AdapterCapsule (That's why
     * there might be multiple AdapterCapsules for one Listener instance (the instance could have been registered multiple times))
     */
    protected WeakHashMap<Adapter, Collection<AdapterCapsule>> notifierByListener = new WeakHashMap<Adapter, Collection<AdapterCapsule>>();

    /**
     * this is needed for performance reasons mainly
     */
    private Collection<AdapterCapsule> allNotifiers = new LinkedList<AdapterCapsule>();

    /**
     * The RegistrationManager does the main work when finding out which listeners are affected by an event.
     */
    private final RegistrationManagerTableBased registrationManager;

    private final WeakHashMap<ResourceSet, Object> resourceSets;

    /**
     * Registered with all {@link WeakReference}s created for {@link Adapter}s
     * during {@link #register(Adapter, AbstractEventFilter, ListenerTypeEnum)
     * registration}. If any of these adapters is no longer strongly referenced
     * and hence eligible for garbage collection, it may not have been properly
     * {@link #deregister(Adapter) deregistered} from this event manager. This
     * would cause structures in the {@link #registrationManager} to remain in
     * place although no longer needed. This, in turn, would leak memory over
     * time.
     */
    private final ReferenceQueue<Adapter> adaptersNoLongerStronglyReferenced = new ReferenceQueue<Adapter>();

    /**
     * This thread polls the {@link #adaptersNoLongerStronglyReferenced}. For any {@link Adapter} that
     * is enqueued, it {@link #deregister(Reference) deregisters} the adapter. The thread will only
     * keep a weak reference to this event manager, hence not disabling the event manager's garbage
     * collection.
     */
    private CleanupThread adapterCleanupThread;

    public EventManagerTableBased(ResourceSet set) {
        this();
        addToObservedResourceSets(set);
    }
    
    public EventManagerTableBased() {
        resourceSets = new WeakHashMap<ResourceSet, Object>();
        registrationManager = new RegistrationManagerTableBased();
        adapterCleanupThread = new CleanupThread(adaptersNoLongerStronglyReferenced, this);
        adapterCleanupThread.start();
    }
    
    public void setActive(boolean active) {
        this.active = active;
    }

    /* Methods from EventRegistry interface */

    /*
     * @see EventRegistry#registerListener(ChangeListener, MoinEventFilter)
     */
    public void subscribe(
            EventFilter eventFilterTree, Adapter listener) {
        register(listener, (AbstractEventFilter) eventFilterTree, ListenerTypeEnum.postChange);
    }

    /*
     * @see EventRegistry#registerPreChangeListener(PreChangeListener, MoinEventFilter)
     */
    public void registerPreChangeListener(Adapter listener, AbstractEventFilter eventFilterTree) {
        register(listener, eventFilterTree, ListenerTypeEnum.preChange);
    }

    public void registerCommitListener(Adapter listener, AbstractEventFilter eventFilterTree) {
        register(listener, eventFilterTree, ListenerTypeEnum.postCommit);
    }

    public void registerPreCommitListener(Adapter listener, AbstractEventFilter eventFilterTree) {
        register(listener, eventFilterTree, ListenerTypeEnum.preCommit);
    }

    /*
     * the following 2 constants define the types of listeners that get a Notifier or DeferringNotifier
     */
    private static final ListenerTypeEnum listenersForNotifier = new ListenerTypeEnum(ListenerTypeEnum.postChange,
            ListenerTypeEnum.preChange);
    private static final ListenerTypeEnum listenersForDeferringNotifier = new ListenerTypeEnum(ListenerTypeEnum.postCommit,
            ListenerTypeEnum.preCommit);

    private void register(Adapter listener, AbstractEventFilter eventFilterTree, ListenerTypeEnum listenerType) {
        // Check preconditions for parameters
        if (listener == null) {
            throw new IllegalArgumentException("Event listener must not be null");
        }
        if (eventFilterTree == null) {
            throw new IllegalArgumentException("Event filter must not be null");
        }
        // Use WeakReference to avoid dangling registrations
        WeakReference<Adapter> listenerRef = new WeakReference<Adapter>(listener, adaptersNoLongerStronglyReferenced);
        // delegate registration to RegistrationManager
        // The event filter is cloned, because the calculation of the DNF will modify the filter tree
        registrationManager.register(eventFilterTree.clone(), listenerRef, listenerType);
        // instantiate and associate notifier
        AdapterCapsule notifier = null;
        if (listenerType.matches(listenersForNotifier)) {
            notifier = new AdapterCapsule(listenerRef, listenerType, this);
        } else if (listenerType.matches(listenersForDeferringNotifier)) {
            notifier = new DeferringNotifier(listenerRef, listenerType, this);
        } else {
            logger.warning("Unkown listenerType "+listenerType);
        }
        addNotifierForListener(notifier);
    }

    public void deregister(Adapter listener) {
        // TODO what if a listener is being removed that has pending events?? -> EventDeferring
        registrationManager.deregister(listener);
        // remove Notifier(s) for listener
        removeListener(listener);
    }
    
    void deregister(Reference<? extends Adapter> listenerRef) {
    	Adapter adapter = listenerRef.get();
    	if (adapter == null) {
    		// WeakHashMaps with adapter as key don't need to be taken care of anymore
    		registrationManager.deregister(listenerRef);
    	} else {
    		deregister(adapter);
    	}
    }

    /* Methods from EventManager interface */

    // private static final ListenerTypeEnum listenerTypesToReceiveChangeEvents = new
    // ListenerTypeEnum(ListenerTypeEnum.postChange,ListenerTypeEnum.preCommit,ListenerTypeEnum.postCommit);
    public void fireChangeEvent(Notification event) {
        if (!doFireEvents)
            return;

        // ((ChangeEventImpl) event).setDedicatedListenerType(listenerTypesToReceiveChangeEvents);
        fireEvent(event);

        // After the "PostEvent" has been fired, the cached information for the pre/post cycle can be deleted
        // If this is not done, the event could not be used for another Session
        // TODO currently not supported
        // ((ChangeEventImpl) event).registrations = null;

    }

    public void firePreChangeEvent(Notification event) {
        if (!doFireEvents)
            return;

        // ((ChangeEventImpl) event).setDedicatedListenerType(ListenerTypeEnum.preChange);
        fireEvent(event);
    }

    public void beginCommand() {
        if (!doFireEvents)
            return;

        for (AdapterCapsule notifier : allNotifiers)
            notifier.deferNotification();
    }

    public void postCommitCommand() {
        if (!doFireEvents)
            return;

        for (AdapterCapsule notifier : allNotifiers)
            if (notifier.getListenerType().matches(ListenerTypeEnum.postCommit))
                notifier.deliverDeferredEvents();

    }

    public void preCommitCommand() {
        if (!doFireEvents)
            return;

        for (AdapterCapsule notifier : allNotifiers)
            if (notifier.getListenerType().matches(ListenerTypeEnum.preCommit))
                notifier.deliverDeferredEvents();

    }

    private static final ListenerTypeEnum allCommitListenerTypes = new ListenerTypeEnum(ListenerTypeEnum.preCommit,
            ListenerTypeEnum.postCommit);

    public void cancelCommand() {
        if (!doFireEvents)
            return;

        for (AdapterCapsule notifier : allNotifiers)
            if (notifier.getListenerType().matches(allCommitListenerTypes))
                notifier.cancelDeferment();

    }

    /**
     * This method notifies all interested listeners by invoking the fireEvent() method on their associated Notifier.
     * 
     * @param event
     *            the event that will be delivered to clients
     */
    private void fireEvent(Notification event) {
        Collection<WeakReference<? extends Adapter>> listeners = registrationManager.getListenersFor(event);
        for (WeakReference<? extends Adapter> listenerRef : listeners) {
            AdapterCapsule notifier = getNotifierForListener(listenerRef, ListenerTypeEnum.postChange);
            if (notifier != null) {
                notifier.fireEvent(event);
            }
        }
    }

    /*
     * ************************************************************************* The following 3 methods
     * (addNotifierForListener,removeListener,getNotifierForListener) are private convenience methods only! They are needed
     * because a listener that implements both ( PreChangeListener and ChangeListener) has to have a seperate Notifier for each
     * role. (several registrations as e.g. PreChangeListener result in only one Notifier) In order to achieve this, a collection
     * of Notifiers is stored for each listener and the notifiers can then be rejected from the Collection if they don't match the
     * required ListenerType. *************************************************************************
     */

    private void addNotifierForListener(AdapterCapsule notifier) {
        Adapter adapter = notifier.getListener().get();
        if (adapter == null) {
            logger.warning("listener "+notifier.getListener()+" got GCed; AdapterCapsule: "+notifier);
        } else {
            Collection<AdapterCapsule> notifiers = notifierByListener.get(adapter);
            if (notifiers == null) {
                notifiers = new LinkedList<AdapterCapsule>();
                notifierByListener.put(adapter, notifiers);
            }
            notifiers.add(notifier);
            allNotifiers.add(notifier);
        }
    }

    private void removeListener(Adapter listener) {
        // maintain allNotifiers-member
        Collection<AdapterCapsule> removedNotifiers = notifierByListener.get(listener);
        if (removedNotifiers != null) {
            allNotifiers.removeAll(removedNotifiers);
        }
        // maintain Map
        notifierByListener.remove(listener);
    }

    private AdapterCapsule getNotifierForListener(WeakReference<? extends Adapter> listener, ListenerTypeEnum listenerType) {
        Adapter adapter = listener.get();
        if (adapter == null) {
            logger.warning("No notifier found for listener "+listener);
        } else {
            Collection<AdapterCapsule> notifiers = notifierByListener.get(adapter);
            if (notifiers == null) {
                logger.warning("No notifiers found");
                return null;
            }
            for (AdapterCapsule notifier : notifiers) {
                if (notifier.isResponsibleFor(adapter, listenerType)) {
                    return notifier;
                }
            }
        }
        logger.warning("No notifier found");
        return null;
    }

    public void handleEMFEvent(Notification notification) {
        if (active) {
            if (!notifierByListener.isEmpty()) {
                for (Notification n : EventManagerFactory.eINSTANCE.createNotificationForComposites(notification)) {
                    fireChangeEvent(n);
                }
            }
        }
    }

    public boolean unsubscribe(Adapter caller) {
        deregister(caller);
        return true;

    }

    @Override
    protected void finalize() throws Throwable {
    	adapterCleanupThread.stopCleaner();
        for (ResourceSet rs : resourceSets.keySet()) {
            if (rs != null && adapter != null) {
                rs.eAdapters().remove(adapter);
            }
        }
        super.finalize();
    }
    /*
     * EventDeferment will not be implemented yet:
     */

    /*
     * This method switches session scoped event deferment. This will result in the deferment of all events if the {@link
     * deferEvents} flag is set true. No listeners that are currently connected to the SessionEventManager will receive events.
     * The queued events are delivered when the operation is called and the {@link deferEvents} flag is set to false. If the
     * session scoped deferment overrides a client scoped deferment, the previous setting will be restored afterwards. @param
     * deferEvents - a flag indicating whether event deferring is switched on or off
     */
    /*
     * public void setEventDeferring(boolean deferEvents) { for (Iterator it = notifierByListener.values().iterator();
     * it.hasNext();) { Object notifier = it.next(); if (notifier instanceof DeferrableNotifier) { ((DeferrableNotifier) notifier)
     * .setGlobalEventDeferring(deferEvents); } } }
     */
    /*
     * This method switches client specific event deferment. If the {@link deferEvents} flag is set to true, no events will be
     * delivered to the specified listener. The {@link notificationTrigger} set is used to specify event types that trigger the
     * delivery of all currently queued events. The deferment will stay active in that case. When the operation is called and the
     * {@link deferEvents} flag is set to false, the deferment will be turned off and all pending events will be delivered to the
     * listener. @param listener - the affected listener @param deferEvents - a flag indicating whether the event deferment is
     * switched on or off @param notificationTrigger - a set of event types that trigger the automatic delivery of queued events.
     * The type of the contained elements is {@link java.lang.Class}
     */

    /*
     * public void setEventDeferring(ChangeListener listener, boolean deferEvents, Set notificationTrigger) { /* TODO move
     * exception-message to xlf-file (but probably this method will be removed anyway) //only (post)ChangeListeners can be
     * deferred... DeferrableNotifier notifier = (DeferrableNotifier) getNotifierForListener( listener,
     * ChangeEvent.NOTIFICATIONTIME_AFTER_CHANGE); if (notifier == null) throw new IllegalStateException( "Cannot switch
     * EventDeferring on listener that is not registered yet."); notifier.setEventDeferment(deferEvents);
     * notifier.setNotificationTrigger(notificationTrigger); }
     */
    
    public String toString() {
        return registrationManager.toString();
    }

    public void addToObservedResourceSets(ResourceSet resourceSet) {
        if (!resourceSet.eAdapters().contains(adapter)) {
            resourceSet.eAdapters().add(adapter);
        }
        resourceSets.put(resourceSet, null);
    }

    public void removeFromObservedResourceSets(ResourceSet resourceSet) {
        resourceSet.eAdapters().remove(adapter);
        resourceSets.remove(resourceSet);
    }
}
