/**
 *******************************************************************************
 * Copyright (C) 2001-2002, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
 * $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/impl/ICUService.java,v $
 * $Date: 2002/08/13 23:40:52 $
 * $Revision: 1.7 $
 *
 *******************************************************************************
 */
package com.ibm.icu.impl;

import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EventListener;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

/**
 * <p>A Service provides access to service objects that implement a
 * particular service, e.g. transliterators.  Users provide a String
 * id (for example, a locale string) to the service, and get back an
 * object for that id.  Service objects can be any kind of object.
 * The service object is cached and returned for later queries, so
 * generally it should not be mutable, or the caller should clone the
 * object before modifying it.</p>
 *
 * <p>Services 'canonicalize' the query id and use the canonical id
 * to query for the service.  The service also defines a mechanism
 * to 'fallback' the id multiple times.  Clients can optionally
 * request the actual id that was matched by a query when they
 * use an id to retrieve a service object.</p>
 *
 * <p>Service objects are instantiated by Factory objects registered with 
 * the service.  The service queries each Factory in turn, from most recently
 * registered to earliest registered, until one returns a service object.
 * If none responds with a service object, a fallback id is generated,
 * and the process repeats until a service object is returned or until
 * the id has no further fallbacks.</p>
 *
 * <p>Factories can be dynamically registered and unregistered with the
 * service.  When registered, a Factory is installed at the head of
 * the factory list, and so gets 'first crack' at any keys or fallback
 * keys.  When unregistered, it is removed from the service and can no
 * longer be located through it.  Service objects generated by this
 * factory and held by the client are unaffected.</p>
 *
 * <p>Internally, ICUService uses Keys to query factories and perform
 * fallback.  The Key defines the canonical form of the id, and
 * implements the fallback strategy.  Custom Keys can be defined that
 * parse complex IDs into components that Factories can more easily
 * use.  The Key can cache the results of this parsing to save
 * repeated effort.</p>
 *
 * <p>ICUService implements ICUNotifier, so that clients can register
 * to receive notification when factories are added or removed from 
 * the service.  ICUService provides a default EventListener subinterface,
 * ServiceListener, which can be registered with the service.  When
 * the service changes, the ServiceListener's serviceChanged method
 * is called, with the service as the only argument.</p>
 *
 * <p>The ICUService API is both rich and generic, and it is expected
 * that most implementations will statically 'wrap' ICUService to
 * present a more appropriate API-- for example, to declare the type
 * of the objects returned from get, to limit the factories that can
 * be registered with the service, or to define their own listener
 * interface with a custom callback method.  They might also customize
 * ICUService by overriding it, for example, to customize the Key and
 * fallback strategy.  ICULocaleService is a customized service that
 * uses Locale names as ids and uses Keys that implement the standard
 * resource bundle fallback strategy.<p>
 */
public class ICUService extends ICUNotifier {
    /**
     * Access to factories is protected by a read-write lock.  This is
     * to allow multiple threads to read concurrently, but keep
     * changes to the factory list atomic with respect to all readers.  
     */
    private final ICURWLock factoryLock = new ICURWLock();

    /**
     * All the factories registered with this service.
     */
    private final List factories = new ArrayList();

    /**
     * Keys define how ids are canonicalized, and determine the
     * fallback strategy used when querying the factories.  The default
     * key just takes as its canonicalID the id assigned to it when it
     * is constructed, and has no fallbacks.
     */
    public static class Key {
        private final String id;

	/**
	 * Construct a key from an id.
	 */
        public Key(String id) {
            this.id = id;
        }

        /**
         * Return the original ID.
         */
        public final String id() {
            return id;
        }

        /**
         * Return the canonical version of the original ID.  This implementation
	 * returns the original ID unchanged.
         */
        public String canonicalID() {
            return id;
        }

        /**
         * Return the (canonical) current ID.  This implementation returns the
	 * canonical ID.
         */
        public String currentID() {
            return canonicalID();
        }

        /**
         * If the key has a fallback, modify the key and return true,
         * otherwise return false.  The current ID will change if there
	 * is a fallback.  No currentIDs should be repeated, and fallback
	 * must eventually return false.  This implmentation has no fallbacks
	 * and always returns false.
	 */
        public boolean fallback() {
            return false;
        }
    }

    /**
     * Factories generate the service objects maintained by the
     * service.  A factory generates a service object from a key,
     * updates id->factory mappings, and returns the display name for
     * a supported id.  
     */
    public static interface Factory {
        /**
         * Create a service object from the key, if this factory
         * supports the key.  Otherwise, return null.  
	 */
        public Object create(Key key);

	/**
	 * Add IDs understood by this factory to the result map, with
	 * this factory as the value. If this factory hides IDs
	 * currently in result, it should remove or reset the mappings
	 * for those IDs.  
	 */
	public void updateVisibleIDs(Map result);

	/**
	 * Return the display name for this id in the provided locale.
	 * If the id is not visible or not defined by the factory,
	 * return null.  
	 */
	public String getDisplayName(String id, Locale locale);
    }

    /**
     * A default implementation of factory.  This provides default
     * implementations for subclasses, and implements a singleton
     * factory that matches a single id and returns a single
     * (possibly deferred-initialized) instance.  If visible is
     * true, updates the map passed to updateVisibleIDs with a
     * mapping from id to itself.
     */
    public static class SimpleFactory implements Factory {
	protected Object instance;
	protected String id;
	protected boolean visible;

	/**
	 * Convenience constructor that calls SimpleFactory(Object, String, boolean)
	 * with visible true.
	 */
	public SimpleFactory(Object instance, String id) {
	    this(instance, id, true);
	}

	/**
	 * Construct a simple factory that maps a single id to a single 
	 * service instance.  If visible is true, the id will be visible.
	 * Neither the instance nor the id can be null.
	 */
	public SimpleFactory(Object instance, String id, boolean visible) {
	    if (instance == null || id == null) {
		throw new IllegalArgumentException("Instance or id is null");
	    }
	    this.instance = instance;
	    this.id = id;
	    this.visible = visible;
	}

	/**
	 * Return the service instance if id equals the key's currentID.
	 */
	public Object create(Key key) {
	    if (id.equals(key.currentID())) {
		return instance;
	    }
	    return null;
	}

	/**
	 * If visible, adds a mapping from id -> this to the result.
	 */
	public void updateVisibleIDs(Map result) {
	    if (visible) result.put(id, this);
	}

	/**
	 * If id equals this.id, returns id regardless of locale, otherwise
	 * returns null.
	 */
	public String getDisplayName(String id, Locale locale) {
	    return (visible && id.equals(this.id)) ? id : null;
	}
    }

    /**
     * Convenience override for get(String, String[]).
     */
    public Object get(String id) {
	return get(id, null);
    }

    /**
     * <p>Given an id, return a service object, and, if actualIDReturn
     * is not null, the actual id under which it was found in the
     * first element of actualIDReturn.  If no service object matches
     * this id, return null, and leave actualIDReturn unchanged.</p>
     *
     * <p>This tries each registered factory in order, and if none can
     * generate a service object for the key, repeats the process with
     * each fallback of the key until one returns a service object, or
     * the key has no fallback.</p> 
     */
    public Object get(String id, String[] actualIDReturn) {
	if (id == null) {
	    throw new NullPointerException();
	}
	if (factories.size() == 0) {
	    return null;
	}
	
	CacheEntry result = null;
	Key key = createKey(id);
	if (key != null) {
	    try {
		// The factory list can't be modified until we're done, 
		// otherwise we might update the cache with an invalid result.
		// The cache has to stay in synch with the factory list.
		factoryLock.acquireRead(); 

		Map cache = null;
		SoftReference cref = cacheref; // copy so we don't need to sync on this 
		if (cref != null) {
		    cache = (Map)cref.get();
		}
		if (cache == null) {
		    // synchronized since additions and queries on the cache must be atomic
		    // they can be interleaved, though
		    cache = Collections.synchronizedMap(new HashMap());
		    cref = new SoftReference(cache);
		}

		String currentID = null;
		ArrayList cacheIDList = null;
		boolean putInCache = false;
	    outer:
		do {
		    currentID = key.currentID();

		    result = (CacheEntry)cache.get(currentID);
		    if (result != null) {
			break outer;
		    }

		    // first test of cache failed, so we'll have to update
		    // the cache if we eventually succeed.
		    putInCache = true;

		    Iterator fi = factories.iterator();
		    while (fi.hasNext()) {
			Object service = ((Factory)fi.next()).create(key);
			if (service != null) {
			    result = new CacheEntry(currentID, service);
			    break outer;
			}
		    }

		    // prepare to load the cache with all additional ids that 
		    // will resolve to result, assuming we'll succeed.  We
		    // don't want to keep querying on an id that's going to
		    // fallback to the one that succeeded, we want to hit the
		    // cache the first time next goaround.
		    if (cacheIDList == null) {
			cacheIDList = new ArrayList(5);
		    }
		    cacheIDList.add(currentID);

		} while (key.fallback());

		if (result != null) {
		    if (putInCache) {
			cache.put(result.actualID, result);
			if (cacheIDList != null) {
			    Iterator iter = cacheIDList.iterator();
			    while (iter.hasNext()) {
				cache.put((String)iter.next(), result);
			    }
			}
			// Atomic update.  We held the read lock all this time
			// so we know our cache is consistent with the factory list.
			// We might stomp over a cache that some other thread 
			// rebuilt, but that's the breaks.  They're both good.
			cacheref = cref;
		    }

		    if (actualIDReturn != null) {
			actualIDReturn[0] = result.actualID;
		    }

		    return result.service;
		}
	    }
	    finally {
		factoryLock.releaseRead();
	    }
	}

	return null;
    }
    private SoftReference cacheref;
    
    // Record the actual id for this service in the cache, so we can return it
    // even if we succeed later with a different id.
    private static final class CacheEntry {
	String actualID;
	Object service;
	CacheEntry(String actualID, Object service) {
	    this.actualID = actualID;
	    this.service = service;
	}
    }

    /**
     * Return a snapshot of the visible IDs for this service.  This
     * set will not change as Factories are added or removed, but the
     * supported ids will, so there is no guarantee that all and only
     * the ids in the returned set are visible and supported by the
     * service in subsequent calls.
     */
    public Set getVisibleIDs() {
	return getVisibleIDMap().keySet();
    }

    /**
     * Return a map from visible ids to factories.  
     */
    private Map getVisibleIDMap() {
        Map idcache = null;
	SoftReference ref = idref;
        if (ref != null) {
            idcache = (Map)ref.get();
        }
        while (idcache == null) {
	    synchronized (this) { // or idref-only lock?
		if (ref == idref || idref == null) {
		    // no other thread updated idref before we got the lock, so
		    // grab the factory list and update it ourselves
		    try {
			factoryLock.acquireRead();

			idcache = new TreeMap(String.CASE_INSENSITIVE_ORDER);

			ListIterator lIter = factories.listIterator(factories.size());
			while (lIter.hasPrevious()) {
			    Factory f = (Factory)lIter.previous();
			    f.updateVisibleIDs(idcache);
			}
			idcache = Collections.unmodifiableMap(idcache);
			idref = new SoftReference(idcache);
		    }
		    finally {
			factoryLock.releaseRead();
		    }
		} else {
		    // another thread updated idref, but gc may have stepped
		    // in and undone its work, leaving idcache null.  If so,
		    // retry.
		    ref = idref;
		    idcache = (Map)ref.get();
		}
	    }
        }

        return idcache;
    }
    private SoftReference idref;

    /**
     * Convenience override for getDisplayName(String, Locale) that
     * uses the current default locale.
     */
    public String getDisplayName(String id) {
	return getDisplayName(id, Locale.getDefault());
    }

    /**
     * Given a visible id, return the display name in the requested locale.
     * If there is no directly supported id corresponding to this id, return
     * null.
     */
    public String getDisplayName(String id, Locale locale) {
	Map m = getVisibleIDMap();
	Factory f = (Factory)m.get(id);
	return f != null ? f.getDisplayName(id, locale) : null;
    }

    /**
     * Convenience override of getDisplayNames(Locale) that uses the
     * current default Locale.
     */
    public Map getDisplayNames() {
	return getDisplayNames(Locale.getDefault());
    }

    /**
     * Return a snapshot of the mapping from display names to visible
     * IDs for this service.  This set will not change as factories
     * are added or removed, but the supported ids will, so there is
     * no guarantee that all and only the ids in the returned map will
     * be visible and supported by the service in subsequent calls,
     * nor is there any guarantee that the current display names match
     * those in the set.
     */
    public Map getDisplayNames(Locale locale) {
        Map dncache = null;
	LocaleRef ref = dnref;
        if (ref != null) {
            dncache = ref.get(locale);
        }
        while (dncache == null) {
	    synchronized (this) {
		if (ref == dnref || dnref == null) {
		    dncache = new TreeMap(String.CASE_INSENSITIVE_ORDER);
		    //dncache = new TreeMap(/* locale-specific collator */);
		    
		    Map m = getVisibleIDMap();
		    Iterator ei = m.entrySet().iterator();
		    while (ei.hasNext()) {
			Entry e = (Entry)ei.next();
			String id = (String)e.getKey();
			Factory f = (Factory)e.getValue();
			dncache.put(f.getDisplayName(id, locale), id);
		    }

		    dncache = Collections.unmodifiableMap(dncache);
		    dnref = new LocaleRef(dncache, locale);
		} else {
		    ref = dnref;
		    dncache = ref.get(locale);
		}
	    }
        }

        return dncache;
    }
    // we define a class so we get atomic simultaneous access to both the 
    // locale and corresponding map
    private static class LocaleRef {
	Locale locale;
	SoftReference ref;

	LocaleRef(Map dnCache, Locale locale) {
	    this.locale = locale;
	    this.ref = new SoftReference(dnCache);
	}

	Map get(Locale locale) {
	    if (this.locale.equals(locale)) {
		return (Map)ref.get();
	    }
	    return null;
	}
    }
    private LocaleRef dnref;

    /**
     * Return a snapshot of the currently registered factories.  There
     * is no guarantee that the list will still match the current
     * factory list of the service subsequent to this call.  
     */
    public final List factories() {
	try {
	    factoryLock.acquireRead();
	    return new ArrayList(factories);
	}
	finally{
	    factoryLock.releaseRead();
	}
    }

    /**
     * A convenience override of registerObject(Object, String, boolean)
     * that defaults visible to true.
     */
    public Factory registerObject(Object obj, String id) {
        return registerObject(obj, id, true);
    }

    /**
     * Register an object with the provided id.  The id will be 
     * canonicalized.  The canonicalized ID will be returned by
     * getVisibleIDs if visible is true.
     */
    public Factory registerObject(Object obj, String id, boolean visible) {
	id = createKey(id).canonicalID();
	return registerFactory(new SimpleFactory(obj, id, visible));
    }
    
    /**
     * Register a Factory.  Returns the factory if the service accepts
     * the factory, otherwise returns null.  The default implementation
     * accepts all factories.
     */
    public final Factory registerFactory(Factory factory) {
        if (factory == null) {
            throw new NullPointerException();
        }
	try {
	    factoryLock.acquireWrite();
	    factories.add(0, factory);
	    clearCaches();
	}
	finally {
	    factoryLock.releaseWrite();
	}
	notifyChanged();
	return factory;
    }

    /**
     * Unregister a factory.  The first matching registered factory will
     * be removed from the list.  Returns true if a matching factory was
     * removed.
     */
    public final boolean unregisterFactory(Factory factory) {
	if (factory == null) {
	    throw new NullPointerException();
	}

	boolean result = false;
	try {
	    factoryLock.acquireWrite();
	    if (factories.remove(factory)) {
		result = true;
		clearCaches();
	    }
	}
	finally {
	    factoryLock.releaseWrite();
	}

	if (result) {
	    notifyChanged();
	}
	return result;
    }

    /**
     * Reset the service to the default factories.  The factory
     * lock is acquired and then reInitializeFactories is called.
     */
    public final void reset() {
	try {
	    factoryLock.acquireWrite();
	    reInitializeFactories();
	    clearCaches();
	}
	finally {
	    factoryLock.releaseWrite();
	}
	notifyChanged();
    }

    /**
     * Reinitialize the factory list to its default state.  By default
     * this clears the list.  Subclasses can override to provide other
     * default initialization of the factory list.  Subclasses must
     * not call this method directly, as it must only be called while
     * holding write access to the factory list.  
     */
    protected void reInitializeFactories() {
	factories.clear();
    }

    /**
     * Create a key from an id.  This creates a Key instance.
     * Subclasses can override to define more useful keys appropriate
     * to the factories they accept.
     */
    protected Key createKey(String id) {
        return new Key(id);
    }

    /**
     * Clear caches maintained by this service.  Subclasses can
     * override if they implement additional that need to be cleared
     * when the service changes. Subclasses should generally not call
     * this method directly, as it must only be called while
     * synchronized on this.
     */
    protected void clearCaches() {
	// we don't synchronize on these because methods that use them
	// copy before use, and check for changes if they modify the
	// caches.
	cacheref = null;
	idref = null;
	dnref = null;
    }

    /**
     * Clears only the service cache.
     * This can be called by subclasses when a change affects the service
     * cache but not the id caches, e.g., when the default locale changes
     * the resolution of ids changes, but not the visible ids themselves.
     */
    protected void clearServiceCache() {
	cacheref = null;
    }

    /**
     * ServiceListener is the listener that ICUService provides by default.
     * ICUService will notifiy this listener when factories are added to
     * or removed from the service.  Subclasses can provide
     * different listener interfaces that extend EventListener, and modify
     * acceptsListener and notifyListener as appropriate.
     */
    public static interface ServiceListener extends EventListener {
	public void serviceChanged(ICUService service);
    }

    /**
     * Return true if the listener is accepted; by default this
     * requires a ServiceListener.  Subclasses can override to accept
     * different listeners.  
     */
    protected boolean acceptsListener(EventListener l) {
	return l instanceof ServiceListener;
    }

    /**
     * Notify the listener, which by default is a ServiceListener.
     * Subclasses can override to use a different listener.  
     */
    protected void notifyListener(EventListener l) {
	((ServiceListener)l).serviceChanged(this);
    }

    /**
     * Return a string describing the statistics for this service.
     * This also resets the statistics. Used for debugging purposes.
     */
    public String stats() {
	ICURWLock.Stats stats = factoryLock.resetStats();
	if (stats != null) {
	    return stats.toString();
	}
	return "no stats";
    }
}

