/*******************************************************************************
 * Copyright (c) 2001, 2005 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
 *******************************************************************************/
package org.eclipse.jem.internal.proxy.ide;

/*
 * $RCSfile: IDEStandardBeanTypeProxyFactory.java,v $ $Revision: 1.12 $ $Date: 2005/08/24 20:39:06 $
 */

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.MessageFormat;
import java.util.*;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

import org.eclipse.jem.internal.proxy.common.MapTypes;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.internal.proxy.core.ExpressionProxy.ProxyEvent;

public class IDEStandardBeanTypeProxyFactory implements IStandardBeanTypeProxyFactory {

	protected final IDEProxyFactoryRegistry fFactoryRegistry;

	// Hashtable to cache proxies for classes so they are found on second and subsequent lookups
	protected Map beanProxies;

	public static Map MAP_SHORTSIG_TO_TYPE = new HashMap(8);

	public static Map MAP_TYPENAME_TO_SHORTSIG = new HashMap(8);

	static {
		MAP_SHORTSIG_TO_TYPE.put("B", Byte.TYPE); //$NON-NLS-1$
		MAP_SHORTSIG_TO_TYPE.put("C", Character.TYPE); //$NON-NLS-1$
		MAP_SHORTSIG_TO_TYPE.put("D", Double.TYPE); //$NON-NLS-1$
		MAP_SHORTSIG_TO_TYPE.put("F", Float.TYPE); //$NON-NLS-1$
		MAP_SHORTSIG_TO_TYPE.put("I", Integer.TYPE); //$NON-NLS-1$
		MAP_SHORTSIG_TO_TYPE.put("J", Long.TYPE); //$NON-NLS-1$
		MAP_SHORTSIG_TO_TYPE.put("S", Short.TYPE); //$NON-NLS-1$
		MAP_SHORTSIG_TO_TYPE.put("Z", Boolean.TYPE); //$NON-NLS-1$

		MAP_TYPENAME_TO_SHORTSIG.put("byte", "B"); //$NON-NLS-1$ //$NON-NLS-2$
		MAP_TYPENAME_TO_SHORTSIG.put("char", "C"); //$NON-NLS-1$ //$NON-NLS-2$
		MAP_TYPENAME_TO_SHORTSIG.put("double", "D"); //$NON-NLS-1$ //$NON-NLS-2$
		MAP_TYPENAME_TO_SHORTSIG.put("float", "F"); //$NON-NLS-1$ //$NON-NLS-2$
		MAP_TYPENAME_TO_SHORTSIG.put("int", "I"); //$NON-NLS-1$ //$NON-NLS-2$
		MAP_TYPENAME_TO_SHORTSIG.put("long", "J"); //$NON-NLS-1$ //$NON-NLS-2$
		MAP_TYPENAME_TO_SHORTSIG.put("short", "S"); //$NON-NLS-1$ //$NON-NLS-2$
		MAP_TYPENAME_TO_SHORTSIG.put("boolean", "Z"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	// Cached copy of a few typical bean type proxies.
	IDEBeanTypeProxy objectClass;

	IDEBooleanTypeBeanTypeProxy booleanType;

	IDEBooleanClassBeanTypeProxy booleanClass;

	IDEIntegerTypeBeanTypeProxy intType;

	IDEIntegerClassBeanTypeProxy integerClass;

	IDEFloatTypeBeanTypeProxy floatType;

	IDEFloatClassBeanTypeProxy floatClass;

	IDELongTypeBeanTypeProxy longType;

	IDELongClassBeanTypeProxy longClass;

	IDEShortTypeBeanTypeProxy shortType;

	IDEShortClassBeanTypeProxy shortClass;

	IDEByteTypeBeanTypeProxy byteType;

	IDEByteClassBeanTypeProxy byteClass;

	IDECharTypeBeanTypeProxy charType;

	IDECharacterClassBeanTypeProxy charClass;

	IDEDoubleTypeBeanTypeProxy doubleType;

	IDEDoubleClassBeanTypeProxy doubleClass;

	IDEStringBeanTypeProxy stringClass;

	IDEClassBeanTypeProxy classClass;

	IDEBeanTypeProxy voidType;

	public IDEStandardBeanTypeProxyFactory(IDEProxyFactoryRegistry aRegistry) {
		fFactoryRegistry = aRegistry;
		aRegistry.registerBeanTypeProxyFactory(this);

		// Now initialize the cache.
		objectClass = new IDEBeanTypeProxy(fFactoryRegistry, Object.class);
		booleanType = new IDEBooleanTypeBeanTypeProxy(fFactoryRegistry, Boolean.TYPE);
		booleanClass = new IDEBooleanClassBeanTypeProxy(fFactoryRegistry, Boolean.class);
		intType = new IDEIntegerTypeBeanTypeProxy(fFactoryRegistry, Integer.TYPE);
		integerClass = new IDEIntegerClassBeanTypeProxy(fFactoryRegistry, Integer.class);
		floatType = new IDEFloatTypeBeanTypeProxy(fFactoryRegistry, Float.TYPE);
		floatClass = new IDEFloatClassBeanTypeProxy(fFactoryRegistry, Float.class);
		longType = new IDELongTypeBeanTypeProxy(fFactoryRegistry, Long.TYPE);
		longClass = new IDELongClassBeanTypeProxy(fFactoryRegistry, Long.class);
		shortType = new IDEShortTypeBeanTypeProxy(fFactoryRegistry, Short.TYPE);
		shortClass = new IDEShortClassBeanTypeProxy(fFactoryRegistry, Short.class);
		byteType = new IDEByteTypeBeanTypeProxy(fFactoryRegistry, Byte.TYPE);
		byteClass = new IDEByteClassBeanTypeProxy(fFactoryRegistry, Byte.class);
		charType = new IDECharTypeBeanTypeProxy(fFactoryRegistry, Character.TYPE);
		charClass = new IDECharacterClassBeanTypeProxy(fFactoryRegistry, Character.class);
		doubleType = new IDEDoubleTypeBeanTypeProxy(fFactoryRegistry, Double.TYPE);
		doubleClass = new IDEDoubleClassBeanTypeProxy(fFactoryRegistry, Double.class);
		stringClass = new IDEStringBeanTypeProxy(fFactoryRegistry, String.class);
		classClass = new IDEClassBeanTypeProxy(fFactoryRegistry, java.lang.Class.class);
		voidType = new IDEBeanTypeProxy(fFactoryRegistry, Void.TYPE);

		// Initialize the hashtable with the primitives, their lang equivalents, and also common classes like String
		beanProxies = new HashMap(20);

		// Primitives
		beanProxies.put(intType.getTypeName(), intType);
		beanProxies.put(booleanType.getTypeName(), booleanType);
		beanProxies.put(charType.getTypeName(), charType);
		beanProxies.put(byteType.getTypeName(), byteType);
		beanProxies.put(shortType.getTypeName(), shortType);
		beanProxies.put(longType.getTypeName(), longType);
		beanProxies.put(floatType.getTypeName(), floatType);
		beanProxies.put(doubleType.getTypeName(), doubleType);

		// java.lang primitive peers
		// Note that special classes are used for some of these which allow the IDE to get the
		// lang objects from the objects that are holding proxies
		beanProxies.put(integerClass.getTypeName(), integerClass);
		beanProxies.put(booleanClass.getTypeName(), booleanClass);
		beanProxies.put(charClass.getTypeName(), charClass);
		beanProxies.put(byteClass.getTypeName(), byteClass);
		beanProxies.put(shortClass.getTypeName(), shortClass);
		beanProxies.put(longClass.getTypeName(), longClass);
		beanProxies.put(floatClass.getTypeName(), floatClass);
		beanProxies.put(doubleClass.getTypeName(), doubleClass);
		beanProxies.put(BigDecimal.class.getName(), new IDEBigDecimalBeanTypeProxy(fFactoryRegistry, BigDecimal.class));//$NON-NLS-1$
		beanProxies.put(BigInteger.class.getName(), new IDEBigIntegerBeanTypeProxy(fFactoryRegistry, BigInteger.class));//$NON-NLS-1$		
		beanProxies.put(stringClass.getTypeName(), stringClass);

		beanProxies.put(classClass.getTypeName(), classClass);
		beanProxies.put(voidType.getTypeName(), voidType);
	}

	/**
	 * We are an IDE proxy and know that the type is in the same VM as the IDE. the IDEBeanTypeProxy object NOTE This is package protected because the
	 * only person who can call it are priveledged classes that are also creating things in an IDEProxy environment. If anyone needs to make this
	 * method public they are doing the wrong thing as they should use the public method getBeanTypeProxy(String) that is on the interface. The only
	 * other object that can guarantee that they have the class for the argument are those that are part of the idevm package
	 */
	IBeanTypeProxy getBeanTypeProxy(Class anIDEClass) {
		return getBeanTypeProxy(anIDEClass.getName());

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(java.lang.String)
	 */
	public synchronized IBeanTypeProxy getBeanTypeProxy(String typeName) {
		typeName = MapTypes.getJNIFormatName(typeName);

		// See whether we already have the proxy for the argument name
		IProxyBeanType beanTypeProxy = (IProxyBeanType) beanProxies.get(typeName);
		// See if there and resolved, if so, return it. If not resolved, that means we need it NOW
		// so we must go for it. When finally resolved the original ExpressionProxy will be deregistered and
		// the resolved beantypeproxy will be in its place.
		if (beanTypeProxy != null && beanTypeProxy.isBeanProxy()) {
			return (IBeanTypeProxy) beanTypeProxy;
		}

		// If not an array, then see if the package extension mechanism can find it.
		// Do this here so that if it is found in the package extension we won't necessarily create an
		// extra connection when not needed.
		if (typeName.charAt(0) != '[') {
			// It is not an array
			// First check with the factory for the package of the class.
			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
			// the package ended and the class started.
			int packageIndex = typeName.lastIndexOf('.');
			if (packageIndex != -1) {
				String packageName = typeName.substring(0, packageIndex);
				IDEExtensionBeanTypeProxyFactory packageFactory = (IDEExtensionBeanTypeProxyFactory) fFactoryRegistry
						.getBeanTypeProxyFactoryExtension(packageName);
				if (packageFactory != null) {
					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName);
					if (beanTypeProxy != null) {
						registerBeanTypeProxy((IBeanTypeProxy) beanTypeProxy, false);
						return (IBeanTypeProxy) beanTypeProxy;
					}
				}
			}
			// There was not a registered factory that dealt with the class. Load it using the factory
			// registry which has the plugin's class loader
			try {
				Class ideClass = fFactoryRegistry.loadClass(typeName);
				IDEBeanTypeProxy superTypeProxy = null;
				if (ideClass.getSuperclass() != null) {
					// Get the beantype proxy of the superclass.
					superTypeProxy = (IDEBeanTypeProxy) getBeanTypeProxy(ideClass.getSuperclass());
				}

				// Ask the supertype
				// to create a beantype proxy of the same beantype proxy class.
				// This is so that any subclasses will get the same beantype proxy class
				// for it if it is special.
				if (superTypeProxy != null)
					beanTypeProxy = superTypeProxy.newBeanTypeForClass(ideClass);

				if (beanTypeProxy == null)
					beanTypeProxy = new IDEBeanTypeProxy(fFactoryRegistry, ideClass);
			} catch (ClassNotFoundException e) {
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.INFO, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
				String msg = MessageFormat.format("{0}({1})", new Object[] { e.getClass(), e.getMessage()}); //$NON-NLS-1$
				beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg, e);
			} catch (ExceptionInInitializerError e) {
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
				String msg = MessageFormat.format("{0}({1})", new Object[] { e.getClass(), e.getMessage()}); //$NON-NLS-1$
				beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg, e.getCause());
			} catch (LinkageError e) {
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.WARNING, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e)); //$NON-NLS-1$
				String msg = MessageFormat.format("{0}({1})", new Object[] { e.getClass(), e.getMessage()}); //$NON-NLS-1$
				beanTypeProxy = new IDEInitErrorBeanTypeProxy(fFactoryRegistry, typeName, msg, e);
			}

			// Cache the instance so we can re-use it again
			beanProxies.put(typeName, beanTypeProxy);
			return (IBeanTypeProxy) beanTypeProxy;
		} else {
			// need to create a array of this many dimensions so that we can get the appropriate class for it.
			int dims = typeName.lastIndexOf('[') + 1;
			Class finalComponentType = null;
			if (typeName.charAt(dims) == 'L') {
				// It is a class.
				// Strip off up to the 'L', and the trailing ';'. That is the class name.
				IDEBeanTypeProxy finalType = (IDEBeanTypeProxy) getBeanTypeProxy(typeName.substring(dims + 1, typeName.length() - 1));
				if (finalType != null)
					finalComponentType = finalType.fClass;
			} else {
				// It is a type. Need to map it.
				finalComponentType = (Class) IDEStandardBeanTypeProxyFactory.MAP_SHORTSIG_TO_TYPE.get(typeName.substring(dims, dims + 1));
			}

			if (finalComponentType != null) {
				Object dummyArray = Array.newInstance(finalComponentType, new int[dims]);
				beanTypeProxy = new IDEArrayBeanTypeProxy(fFactoryRegistry, typeName, dummyArray.getClass());
				beanProxies.put(typeName, beanTypeProxy);
			}
			return (IBeanTypeProxy) beanTypeProxy;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IExpression,
	 *      java.lang.String)
	 */
	public synchronized IProxyBeanType getBeanTypeProxy(IExpression expression, String typeName) {
		typeName = MapTypes.getJNIFormatName(typeName);

		// See whether we already have the proxy for the argument name
		IProxyBeanType beanTypeProxy = (IProxyBeanType) beanProxies.get(typeName);
		if (beanTypeProxy != null) { return beanTypeProxy; }
		
		// Now see if an expression proxy cached.
		beanTypeProxy = ((IDEExpression) expression).getBeanType(typeName);
		if (beanTypeProxy != null)
			return beanTypeProxy;		


		// If not an array, then see if the package extension mechanism can find it.
		// Do this here so that if it is found in the package extension we won't necessarily create an
		// extra connection when not needed.
		if (typeName.charAt(0) != '[') {
			// It is not an array
			// First check with the factory for the package of the class.
			// Inner classes have to use the dollar notation since if they didn't we couldn't tell where
			// the package ended and the class started.
			int packageIndex = typeName.lastIndexOf('.');
			if (packageIndex != -1) {
				String packageName = typeName.substring(0, packageIndex);
				IDEExtensionBeanTypeProxyFactory packageFactory = (IDEExtensionBeanTypeProxyFactory) fFactoryRegistry
						.getBeanTypeProxyFactoryExtension(packageName);
				if (packageFactory != null) {
					beanTypeProxy = packageFactory.getExtensionBeanTypeProxy(typeName, expression);
					if (beanTypeProxy != null) {
						registerBeanTypeProxy(beanTypeProxy, false);
						return beanTypeProxy;
					}
				}
			}
		}

		// There was not a registered factory that dealt with the class. So create the expression proxy.
		beanTypeProxy = ((Expression) expression).createBeanTypeExpressionProxy(typeName);
		registerBeanTypeProxy(beanTypeProxy, false);
		return beanTypeProxy;

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(java.lang.String, int)
	 */
	public IBeanTypeProxy getBeanTypeProxy(String componentClassName, int dimensions) {
		return getBeanTypeProxy(getArrayClassname(componentClassName, dimensions));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#getBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IExpression,
	 *      java.lang.String, int)
	 */
	public IProxyBeanType getBeanTypeProxy(IExpression expression, String componentClassName, int dimensions) {
		return getBeanTypeProxy(expression, getArrayClassname(componentClassName, dimensions));
	}

	/**
	 * @param componentClassName
	 * @param dimensions
	 * @return
	 * 
	 * @since 1.1.0
	 */
	protected String getArrayClassname(String componentClassName, int dimensions) {
		String jniComponentTypeName = MapTypes.getJNIFormatName(componentClassName);
		String compType = jniComponentTypeName;
		if (jniComponentTypeName.charAt(0) != '[') {
			// We're not already an array, so create correct template.
			compType = (String) MAP_TYPENAME_TO_SHORTSIG.get(componentClassName);
			if (compType == null) {
				// It is a class, and not a type.
				compType = "L" + jniComponentTypeName + ";"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
		// Now create it with the appropriate number of '[' in front.
		StringBuffer buffer = new StringBuffer(dimensions + compType.length());
		for (int i = 0; i < dimensions; i++)
			buffer.append('[');
		buffer.append(compType);
		return buffer.toString();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IBeanProxyFactory#terminateFactory(boolean)
	 */
	public void terminateFactory(boolean wait) {
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registerBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IBeanTypeProxy,
	 *      boolean)
	 */
	public synchronized void registerBeanTypeProxy(IBeanTypeProxy aBeanTypeProxy, boolean permanent) {
		beanProxies.put(aBeanTypeProxy.getTypeName(), aBeanTypeProxy);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registerBeanTypeProxy(org.eclipse.jem.internal.proxy.core.IProxyBeanType,
	 *      boolean)
	 */
	public void registerBeanTypeProxy(IProxyBeanType aProxyBeanType, boolean permanent) {
		if (aProxyBeanType.isBeanProxy())
			registerBeanTypeProxy((IBeanTypeProxy) aProxyBeanType, permanent); // A regular kind, do regular registration.
		else {
			ExpressionProxy beanExpressionProxy = ((ExpressionProxy) aProxyBeanType);
			final String typeName = aProxyBeanType.getTypeName();
			((IDEExpression) beanExpressionProxy.getExpression()).addBeanType(typeName, aProxyBeanType);
			beanExpressionProxy.addProxyListener(new ExpressionProxy.ProxyAdapter() {

				public void proxyResolved(ProxyEvent event) {
					String typeName = ((IProxyBeanType) event.getSource()).getTypeName();
					synchronized (IDEStandardBeanTypeProxyFactory.this) {
						if (!beanProxies.containsKey(typeName)) {
							// It hasn't been resolved through some other means. So this is good. Actually this should never
							// occur because upon resolution we've already registered the bean type proxy through the
							// normal mechanisms. But to be safe, we'll do it here.
							beanProxies.put(typeName, event.getProxy());
						}
					}
				}
				
				public void proxyNotResolved(ExpressionProxy.ProxyEvent event) {
					((IDEExpression) ((ExpressionProxy) event.getSource()).getExpression()).removeBeanType(typeName);
				}
			});
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeRegistered(String)
	 */
	public synchronized boolean isBeanTypeRegistered(String className) {
		return beanProxies.containsKey(MapTypes.getJNIFormatName(className));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#registeredTypes()
	 */
	public Set registeredTypes() {
		return beanProxies.keySet();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isBeanTypeNotFound(String)
	 */
	public boolean isBeanTypeNotFound(String className) {
		// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found.
		// In that case an IDEInitErrorBeanTypeProxy will be created.
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#isMaintainNotFoundTypes()
	 */
	public boolean isMaintainNotFoundTypes() {
		// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found.
		// In that case an IDEInitErrorBeanTypeProxy will be created.
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IStandardBeanTypeProxyFactory#setMaintainNotFoundTypes(boolean)
	 */
	public void setMaintainNotFoundTypes(boolean maintain) {
		// Do nothing. No need for it in IDE system because there will always be a proxy, even when not found.
		// In that case an IDEInitErrorBeanTypeProxy will be created.
	}
}
