/*******************************************************************************
 * Copyright (c) 2009, 2010 Wind River Systems 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:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.debug.edc.services;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.dsf.service.IDsfService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;

@SuppressWarnings("rawtypes")

/**
 * Convenience class to help track DSF services that a given
 * client needs to use.  This class is based on the DsfServicesTracker
 * but is designed to be thread safe so clients can use it to get
 * a service reference from any thread. This is important for EDC
 * services because they are not restricted to the Dsf thread.
 * 
 * @since 2.0
 */
public class EDCServicesTracker {
	
    private static String getServiceFilter(String sessionId) {
        return ("(" + IDsfService.PROP_SESSION_ID + "=" + sessionId + ")").intern();   //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
    }

    final private static class ServiceKey 
    {
        private final String fClassName;
        private final String fFilter;
        private final int fHashCode;
        private final String fHashString;
        
        
        public ServiceKey(Class<?> clazz, String filter) {
            fClassName = clazz != null ? clazz.getName() : null;
            fFilter = filter;
            fHashString =  'C' + (fClassName == null ? "" : fClassName) + //$NON-NLS-1$
        				   'F' + (fFilter == null ? "" : fFilter); //$NON-NLS-1$
            fHashCode = fHashString.hashCode();
        }
        
        @Override
        public boolean equals(Object other) {
        	// hashcodes are not guaranteed to be unique, but objects that are equal must have the same hashcode
        	// thus we can optimize by first comparing hashcodes
            return other instanceof ServiceKey &&
            	((((ServiceKey)other).fHashCode == this.fHashCode) && (((ServiceKey)other).fHashString.equals(this.fHashString))); 
        }
        
        @Override
        public int hashCode() {
        	return fHashCode;
        }
    }
    
    private final String fSessionId;    
    private volatile boolean fDisposed = false;
    private final BundleContext fBundleContext;

	private final Map<ServiceKey,ServiceReference> fServiceReferences = Collections.synchronizedMap(new HashMap<ServiceKey,ServiceReference>());
	private final Map<ServiceReference,Object> fServices = Collections.synchronizedMap(new HashMap<ServiceReference,Object>());
    private final String fServiceFilter;

    private final ServiceListener fListner = new ServiceListener() {
        public void serviceChanged(final ServiceEvent event) {
            // Only listen to unregister events.
            if (event.getType() != ServiceEvent.UNREGISTERING) {
                return;
            }
            
            // If session is not active anymore, just exit.  The tracker should 
            // soon be disposed.
            DsfSession session = DsfSession.getSession(fSessionId);
            if (session == null) {
                return;
            }
            
            handleUnregisterEvent(event);
        }
    };
    
	private void handleUnregisterEvent(ServiceEvent event) {
    	synchronized (fServiceReferences)
    	{
            for (Iterator<Map.Entry<ServiceKey, ServiceReference>> itr = fServiceReferences.entrySet().iterator(); itr.hasNext();) {
                Map.Entry<ServiceKey, ServiceReference> entry = itr.next();
                if ( entry.getValue().equals(event.getServiceReference()) ) {
                    itr.remove();
                }
            }
            if (fServices.remove(event.getServiceReference()) != null) {
                fBundleContext.ungetService(event.getServiceReference());
            }
    	}
    }
    
    /** 
     * Only constructor.
     * @param bundleContext Context of the plugin that the client lives in. 
     * @param sessionId The DSF session that this tracker will be used for. 
     */
    public EDCServicesTracker(BundleContext bundleContext, String sessionId) {
        fSessionId = sessionId;
        fBundleContext = bundleContext;
        fServiceFilter = getServiceFilter(sessionId); 
        try {
            fBundleContext.addServiceListener(fListner, fServiceFilter);
        } catch (InvalidSyntaxException e) {
            assert false : "Invalid session ID syntax"; //$NON-NLS-1$
        }
    }
    
    /**
     * Retrieves a service reference for given service class and optional filter.  
     * Filter should be used if there are multiple instances of the desired service
     * running within the same session. 
     * @param serviceClass class of the desired service
     * @param custom filter to use when searching for the service, this filter will 
     * be used instead of the standard filter so it should also specify the desired 
     * session-ID 
     * @return OSGI service reference object to the desired service, null if not found
     */
    public ServiceReference getServiceReference(Class serviceClass, String filter) {
        if (fDisposed) {
            return null;
        }
        
        // If the session is not active, all of its services are gone.
        DsfSession session = DsfSession.getSession(fSessionId);
        if (session == null) {
            return null;
        }
        
        ServiceKey key = new ServiceKey(serviceClass, filter != null ? filter : fServiceFilter);
        if (fServiceReferences.containsKey(key)) {
            return fServiceReferences.get(key);
        }
        
        try {
            ServiceReference[] references = fBundleContext.getServiceReferences(key.fClassName, key.fFilter);
            assert references == null || references.length <= 1;
            if (references == null || references.length == 0) {
                return null;
            } else {
                fServiceReferences.put(key, references[0]);
                return references[0];
            }
        } catch(InvalidSyntaxException e) {
            assert false : "Invalid session ID syntax"; //$NON-NLS-1$
        } catch(IllegalStateException e) {
            // Can occur when plugin is shutting down.
        }
        return null;
    }
    
    /**
     * Convenience class to retrieve a service based on class name only.
     * @param serviceClass class of the desired service
     * @return instance of the desired service, null if not found
     */
    public <V> V getService(Class<V> serviceClass) {
        return getService(serviceClass, null);
    }
    
    /** 
     * Retrieves the service given service class and optional filter.
     * Filter should be used if there are multiple instances of the desired service
     * running within the same session. 
     * @param serviceClass class of the desired service
     * @param custom filter to use when searching for the service, this filter will 
     * be used instead of the standard filter so it should also specify the desired 
     * session-ID 
     * @return instance of the desired service, null if not found
     */
    @SuppressWarnings("unchecked")
	public <V> V getService(Class<V> serviceClass, String filter) {
        ServiceReference serviceRef = getServiceReference(serviceClass, filter);
        if (serviceRef == null) {
            return null;
        } else {
            if (fServices.containsKey(serviceRef)) {
                return (V)fServices.get(serviceRef);
            } else {
                V service = (V)fBundleContext.getService(serviceRef);
                fServices.put(serviceRef, service);
                return service;
            }
        }
    }
    
    /**
     * Un-gets all the references held by this tracker.  Must be called
     * to avoid leaking OSGI service references.
     */
    public void dispose() {
        assert !fDisposed;
        fDisposed = true;
        doDispose();
    }

	private void doDispose() {
    	synchronized (fServices)
    	{
            try {
                fBundleContext.removeServiceListener(fListner);
                for (Iterator<ServiceReference> itr = fServices.keySet().iterator(); itr.hasNext();) {
                    fBundleContext.ungetService(itr.next());
                }
            } catch (IllegalStateException e) {
                // May be thrown during shutdown (bug 293049).
            }
    	}
        fServices.clear();
        fServiceReferences.clear();
    }

    @Override
    protected void finalize() throws Throwable {
        assert fDisposed;
        super.finalize();
    }
}
