/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM 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:
 *     IBM Corporation - initial API and implementation
 *     David Green - fix factories with non-standard class loading (bug 200068) 
 *     Filip Hrbek - fix thread safety problem described in bug 305863
 *     Sergey Prigogin (Google) - use parameterized types (bug 442021)
 *******************************************************************************/
package org.eclipse.core.internal.runtime;

import java.util.*;
import org.eclipse.core.runtime.*;

/**
 * This class is the standard implementation of <code>IAdapterManager</code>. It provides
 * fast lookup of property values with the following semantics:
 * <ul>
 * <li>At most one factory will be invoked per property lookup
 * <li>If multiple installed factories provide the same adapter, only the first found in
 * the search order will be invoked.
 * <li>The search order from a class with the definition <br>
 * <code>class X extends Y implements A, B</code><br> is as follows: <il>
 * <li>the target's class: X
 * <li>X's superclasses in order to <code>Object</code>
 * <li>a breadth-first traversal of each class's interfaces in the
 * order returned by <code>getInterfaces</code> (in the example, X's 
 * superinterfaces then Y's superinterfaces) </li>
 * </ul>
 * 
 * @see IAdapterFactory
 * @see IAdapterManager
 */
public final class AdapterManager implements IAdapterManager {
	/** 
	 * Cache of adapters for a given adaptable class. Maps String  -> Map
	 * (adaptable class name -> (adapter class name -> factory instance))
	 * Thread safety note: The outer map is synchronized using a synchronized
	 * map wrapper class.  The inner map is not synchronized, but it is immutable
	 * so synchronization is not necessary.
	 */
	private Map<String, Map<String, IAdapterFactory>> adapterLookup;

	/**
	 * Cache of classes for a given type name. Avoids too many loadClass calls.
	 * (factory -> (type name -> Class)).
	 * Thread safety note: Since this structure is a nested hash map, and both
	 * the inner and outer maps are mutable, access to this entire structure is
	 * controlled by the classLookupLock field.  Note the field can still be
	 * nulled concurrently without holding the lock.
	 */
	private Map<IAdapterFactory, Map<String, Class<?>>> classLookup;

	/**
	 * The lock object controlling access to the classLookup data structure.
	 */
	private final Object classLookupLock = new Object();

	/**
	 * Cache of class lookup order (Class -> Class[]). This avoids having to compute often, and
	 * provides clients with quick lookup for instanceOf checks based on type name.
	 * Thread safety note: The map is synchronized using a synchronized
	 * map wrapper class.  The arrays within the map are immutable.
	 */
	private Map<Class<?>, Class<?>[]> classSearchOrderLookup;

	/**
	 * Map of factories, keyed by <code>String</code>, fully qualified class name of
	 * the adaptable class that the factory provides adapters for. Value is a <code>List</code>
	 * of <code>IAdapterFactory</code>.
	 */
	private final HashMap<String, List<IAdapterFactory>> factories;

	private final ArrayList<IAdapterManagerProvider> lazyFactoryProviders;

	private static final AdapterManager singleton = new AdapterManager();

	public static AdapterManager getDefault() {
		return singleton;
	}

	/**
	 * Private constructor to block instance creation.
	 */
	private AdapterManager() {
		factories = new HashMap<String, List<IAdapterFactory>>(5);
		lazyFactoryProviders = new ArrayList<IAdapterManagerProvider>(1);
	}

	/**
	 * Given a type name, add all of the factories that respond to those types into
	 * the given table. Each entry will be keyed by the adapter class name (supplied in
	 * IAdapterFactory.getAdapterList).
	 */
	private void addFactoriesFor(String typeName, Map<String, IAdapterFactory> table) {
		List<IAdapterFactory> factoryList = getFactories().get(typeName);
		if (factoryList == null)
			return;
		for (int i = 0, imax = factoryList.size(); i < imax; i++) {
			IAdapterFactory factory = factoryList.get(i);
			if (factory instanceof IAdapterFactoryExt) {
				String[] adapters = ((IAdapterFactoryExt) factory).getAdapterNames();
				for (int j = 0; j < adapters.length; j++) {
					if (table.get(adapters[j]) == null)
						table.put(adapters[j], factory);
				}
			} else {
				Class<?>[] adapters = factory.getAdapterList();
				for (int j = 0; j < adapters.length; j++) {
					String adapterName = adapters[j].getName();
					if (table.get(adapterName) == null)
						table.put(adapterName, factory);
				}
			}
		}
	}

	private void cacheClassLookup(IAdapterFactory factory, Class<?> clazz) {
		synchronized (classLookupLock) {
			//cache reference to lookup to protect against concurrent flush
			Map<IAdapterFactory, Map<String, Class<?>>> lookup = classLookup;
			if (lookup == null)
				classLookup = lookup = new HashMap<IAdapterFactory, Map<String, Class<?>>>(4);
			Map<String, Class<?>> classes = lookup.get(factory);
			if (classes == null) {
				classes = new HashMap<String, Class<?>>(4);
				lookup.put(factory, classes);
			}
			classes.put(clazz.getName(), clazz);
		}
	}

	private Class<?> cachedClassForName(IAdapterFactory factory, String typeName) {
		synchronized (classLookupLock) {
			Class<?> clazz = null;
			//cache reference to lookup to protect against concurrent flush
			Map<IAdapterFactory, Map<String, Class<?>>> lookup = classLookup;
			if (lookup != null) {
				Map<String, Class<?>> classes = lookup.get(factory);
				if (classes != null) {
					clazz = classes.get(typeName);
				}
			}
			return clazz;
		}
	}

	/**
	 * Returns the class with the given fully qualified name, or null
	 * if that class does not exist or belongs to a plug-in that has not
	 * yet been loaded.
	 */
	private Class<?> classForName(IAdapterFactory factory, String typeName) {
		Class<?> clazz = cachedClassForName(factory, typeName);
		if (clazz == null) {
			if (factory instanceof IAdapterFactoryExt)
				factory = ((IAdapterFactoryExt) factory).loadFactory(false);
			if (factory != null) {
				try {
					clazz = factory.getClass().getClassLoader().loadClass(typeName);
				} catch (ClassNotFoundException e) {
					// it is possible that the default bundle classloader is unaware of this class
					// but the adaptor factory can load it in some other way. See bug 200068.
					if (typeName == null)
						return null;
					Class<?>[] adapterList = factory.getAdapterList();
					clazz = null;
					for (int i = 0; i < adapterList.length; i++) {
						if (typeName.equals(adapterList[i].getName())) {
							clazz = adapterList[i];
							break;
						}
					}
					if (clazz == null)
						return null; // class not yet loaded
				}
				cacheClassLookup(factory, clazz);
			}
		}
		return clazz;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdapterManager#getAdapterTypes(java.lang.Class)
	 */
	@Override
	public String[] computeAdapterTypes(Class<? extends Object> adaptable) {
		Set<String> types = getFactories(adaptable).keySet();
		return types.toArray(new String[types.size()]);
	}

	/**
	 * Computes the adapters that the provided class can adapt to, along
	 * with the factory object that can perform that transformation. Returns 
	 * a table of adapter class name to factory object.
	 * @param adaptable
	 */
	private Map<String, IAdapterFactory> getFactories(Class<? extends Object> adaptable) {
		//cache reference to lookup to protect against concurrent flush
		Map<String, Map<String, IAdapterFactory>> lookup = adapterLookup;
		if (lookup == null)
			adapterLookup = lookup = Collections.synchronizedMap(new HashMap<String, Map<String, IAdapterFactory>>(30));
		Map<String, IAdapterFactory> table = lookup.get(adaptable.getName());
		if (table == null) {
			// calculate adapters for the class
			table = new HashMap<String, IAdapterFactory>(4);
			Class<?>[] classes = computeClassOrder(adaptable);
			for (int i = 0; i < classes.length; i++)
				addFactoriesFor(classes[i].getName(), table);
			// cache the table
			lookup.put(adaptable.getName(), table);
		}
		return table;
	}

	/**
	 * Returns the super-type search order starting with <code>adaptable</code>. 
	 * The search order is defined in this class' comment.
	 */
	@Override
	@SuppressWarnings("unchecked")
	public <T> Class<? super T>[] computeClassOrder(Class<T> adaptable) {
		Class<?>[] classes = null;
		//cache reference to lookup to protect against concurrent flush
		Map<Class<?>, Class<?>[]> lookup = classSearchOrderLookup;
		if (lookup == null)
			classSearchOrderLookup = lookup = Collections.synchronizedMap(new HashMap<Class<?>, Class<?>[]>());
		else
			classes = lookup.get(adaptable);
		// compute class order only if it hasn't been cached before
		if (classes == null) {
			classes = doComputeClassOrder(adaptable);
			lookup.put(adaptable, classes);
		}
		return (Class<? super T>[]) classes;
	}

	/**
	 * Computes the super-type search order starting with <code>adaptable</code>. 
	 * The search order is defined in this class' comment.
	 */
	private Class<?>[] doComputeClassOrder(Class<?> adaptable) {
		List<Class<?>> classes = new ArrayList<Class<?>>();
		Class<?> clazz = adaptable;
		Set<Class<?>> seen = new HashSet<Class<?>>(4);
		//first traverse class hierarchy
		while (clazz != null) {
			classes.add(clazz);
			clazz = clazz.getSuperclass();
		}
		//now traverse interface hierarchy for each class
		Class<?>[] classHierarchy = classes.toArray(new Class[classes.size()]);
		for (int i = 0; i < classHierarchy.length; i++)
			computeInterfaceOrder(classHierarchy[i].getInterfaces(), classes, seen);
		return classes.toArray(new Class[classes.size()]);
	}

	private void computeInterfaceOrder(Class<?>[] interfaces, Collection<Class<?>> classes, Set<Class<?>> seen) {
		List<Class<?>> newInterfaces = new ArrayList<Class<?>>(interfaces.length);
		for (int i = 0; i < interfaces.length; i++) {
			Class<?> interfac = interfaces[i];
			if (seen.add(interfac)) {
				//note we cannot recurse here without changing the resulting interface order
				classes.add(interfac);
				newInterfaces.add(interfac);
			}
		}
		for (Class<?> clazz : newInterfaces)
			computeInterfaceOrder(clazz.getInterfaces(), classes, seen);
	}

	/**
	 * Flushes the cache of adapter search paths. This is generally required whenever an
	 * adapter is added or removed.
	 * <p>
	 * It is likely easier to just toss the whole cache rather than trying to be smart
	 * and remove only those entries affected.
	 * </p>
	 */
	public synchronized void flushLookup() {
		adapterLookup = null;
		classLookup = null;
		classSearchOrderLookup = null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdapterManager#getAdapter(java.lang.Object, java.lang.Class)
	 */
	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(Object adaptable, Class<T> adapterType) {
		Assert.isNotNull(adaptable);
		Assert.isNotNull(adapterType);
		IAdapterFactory factory = getFactories(adaptable.getClass()).get(adapterType.getName());
		T result = null;
		if (factory != null)
			result = factory.getAdapter(adaptable, adapterType);
		if (result == null && adapterType.isInstance(adaptable))
			return (T) adaptable;
		return result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdapterManager#getAdapter(java.lang.Object, java.lang.Class)
	 */
	@Override
	public Object getAdapter(Object adaptable, String adapterType) {
		Assert.isNotNull(adaptable);
		Assert.isNotNull(adapterType);
		return getAdapter(adaptable, adapterType, false);
	}

	/**
	 * Returns an adapter of the given type for the provided adapter.
	 * @param adaptable the object to adapt
	 * @param adapterType the type to adapt the object to
	 * @param force <code>true</code> if the plug-in providing the
	 * factory should be activated if necessary. <code>false</code>
	 * if no plugin activations are desired.
	 */
	private Object getAdapter(Object adaptable, String adapterType, boolean force) {
		IAdapterFactory factory = getFactories(adaptable.getClass()).get(adapterType);
		if (force && factory instanceof IAdapterFactoryExt)
			factory = ((IAdapterFactoryExt) factory).loadFactory(true);
		Object result = null;
		if (factory != null) {
			Class<?> clazz = classForName(factory, adapterType);
			if (clazz != null)
				result = factory.getAdapter(adaptable, clazz);
		}
		if (result == null && adaptable.getClass().getName().equals(adapterType))
			return adaptable;
		return result;
	}

	@Override
	public boolean hasAdapter(Object adaptable, String adapterTypeName) {
		return getFactories(adaptable.getClass()).get(adapterTypeName) != null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdapterManager#queryAdapter(java.lang.Object, java.lang.String)
	 */
	@Override
	public int queryAdapter(Object adaptable, String adapterTypeName) {
		IAdapterFactory factory = getFactories(adaptable.getClass()).get(adapterTypeName);
		if (factory == null)
			return NONE;
		if (factory instanceof IAdapterFactoryExt) {
			factory = ((IAdapterFactoryExt) factory).loadFactory(false); // don't force loading
			if (factory == null)
				return NOT_LOADED;
		}
		return LOADED;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdapterManager#loadAdapter(java.lang.Object, java.lang.String)
	 */
	@Override
	public Object loadAdapter(Object adaptable, String adapterTypeName) {
		return getAdapter(adaptable, adapterTypeName, true);
	}

	/*
	 * @see IAdapterManager#registerAdapters
	 */
	@Override
	public synchronized void registerAdapters(IAdapterFactory factory, Class<?> adaptable) {
		registerFactory(factory, adaptable.getName());
		flushLookup();
	}

	/*
	 * @see IAdapterManager#registerAdapters
	 */
	public void registerFactory(IAdapterFactory factory, String adaptableType) {
		List<IAdapterFactory> list = factories.get(adaptableType);
		if (list == null) {
			list = new ArrayList<IAdapterFactory>(5);
			factories.put(adaptableType, list);
		}
		list.add(factory);
	}

	/*
	 * @see IAdapterManager#unregisterAdapters
	 */
	@Override
	public synchronized void unregisterAdapters(IAdapterFactory factory) {
		for (List<IAdapterFactory> list : factories.values())
			list.remove(factory);
		flushLookup();
	}

	/*
	 * @see IAdapterManager#unregisterAdapters
	 */
	@Override
	public synchronized void unregisterAdapters(IAdapterFactory factory, Class<?> adaptable) {
		List<IAdapterFactory> factoryList = factories.get(adaptable.getName());
		if (factoryList == null)
			return;
		factoryList.remove(factory);
		flushLookup();
	}

	/*
	 * Shuts down the adapter manager by removing all factories
	 * and removing the registry change listener. Should only be
	 * invoked during platform shutdown.
	 */
	public synchronized void unregisterAllAdapters() {
		factories.clear();
		flushLookup();
	}

	public void registerLazyFactoryProvider(IAdapterManagerProvider factoryProvider) {
		synchronized (lazyFactoryProviders) {
			lazyFactoryProviders.add(factoryProvider);
		}
	}

	public boolean unregisterLazyFactoryProvider(IAdapterManagerProvider factoryProvider) {
		synchronized (lazyFactoryProviders) {
			return lazyFactoryProviders.remove(factoryProvider);
		}
	}

	public HashMap<String, List<IAdapterFactory>> getFactories() {
		synchronized (lazyFactoryProviders) {
			while (lazyFactoryProviders.size() > 0) {
				IAdapterManagerProvider provider = lazyFactoryProviders.remove(0);
				if (provider.addFactories(this))
					flushLookup();
			}
		}
		return factories;
	}
}
