/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *******************************************************************************/
/*
 *  $RCSfile: REMMethodProxyFactory.java,v $
 *  $Revision: 1.9 $  $Date: 2005/05/11 19:01:12 $ 
 */
package org.eclipse.jem.internal.proxy.remote;

import java.lang.reflect.AccessibleObject;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.internal.proxy.common.remote.Commands;
import org.eclipse.jem.internal.proxy.common.remote.TransmitableArray;

/**
 * Factory for creating method proxies. Creation date: (12/3/99 6:29:40 PM)
 * 
 * @author: Joe Winchester
 */
public class REMMethodProxyFactory implements IMethodProxyFactory {

	final protected REMProxyFactoryRegistry fFactoryRegistry;

	// Cached copy of a few typical method type proxies.
	IREMBeanTypeProxy accessibleType;

	REMMethodTypeProxy methodType;

	REMFieldTypeProxy fieldType;

	REMConstructorTypeProxy ctorType;

	REMMethodProxy getMethodProxy;

	REMMethodProxyFactory(REMProxyFactoryRegistry aRegistry) {
		fFactoryRegistry = aRegistry;
		aRegistry.registerMethodProxyFactory(this);
		REMStandardBeanTypeProxyFactory typeFactory = (REMStandardBeanTypeProxyFactory) aRegistry.getBeanTypeProxyFactory();

		accessibleType = typeFactory.objectClass.newBeanTypeForClass(new Integer(Commands.ACCESSIBLEOBJECT_CLASS), AccessibleObject.class.getName(),
				false);
		methodType = new REMMethodTypeProxy(aRegistry, accessibleType);
		fieldType = new REMFieldTypeProxy(aRegistry, accessibleType);
		ctorType = new REMConstructorTypeProxy(aRegistry, accessibleType);
		aRegistry.getBeanTypeProxyFactory().registerBeanTypeProxy(accessibleType, true);
		aRegistry.getBeanTypeProxyFactory().registerBeanTypeProxy(methodType, true);
		aRegistry.getBeanTypeProxyFactory().registerBeanTypeProxy(fieldType, true);
		aRegistry.getBeanTypeProxyFactory().registerBeanTypeProxy(ctorType, true);

		getMethodProxy = (REMMethodProxy) methodType.newBeanProxy(new Integer(Commands.GET_METHOD_ID));
		((REMStandardBeanProxyFactory) aRegistry.getBeanProxyFactory()).registerProxy(getMethodProxy);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IMethodProxyFactory#getMethodProxy(java.lang.String, java.lang.String, java.lang.String[])
	 */
	public IMethodProxy getMethodProxy(String className, String methodName, String[] parameterTypes) {
		IStandardBeanTypeProxyFactory typeFactory = fFactoryRegistry.getBeanTypeProxyFactory();
		IBeanTypeProxy clsProxy = typeFactory.getBeanTypeProxy(className);
		if (clsProxy == null)
			return null;
		// This will redirect to the beantype, which will go through the method cache.
		return clsProxy.getMethodProxy(methodName, parameterTypes);
	}
	
	/**
	 * A helper method to get the method proxy for the expression. This is used by registries and beantype proxies. It will go through
	 * the method cache to make sure we get only one.
	 * 
	 * @param expression
	 * @param aBeanTypeProxy
	 * @param methodName
	 * @param parmTypes
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public IProxyMethod getMethodProxy(IExpression expression, IProxyBeanType aBeanTypeProxy, String methodName, IProxyBeanType[] parmTypes){
		return ((REMStandardBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactory()).proxyConstants.getMethodProxy(expression, aBeanTypeProxy, methodName, parmTypes);
	}
	
	/**
	 * A helper method to get the field proxy for the expression. This is used by registries and beantype proxies. It will go through
	 * the method cache to make sure we get only one.
	 * @param expression
	 * @param aBeanTypeProxy
	 * @param fieldName
	 * 
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public IProxyField getFieldProxy(IExpression expression, IProxyBeanType aBeanTypeProxy, String fieldName){
		return ((REMStandardBeanTypeProxyFactory) fFactoryRegistry.getBeanTypeProxyFactory()).proxyConstants.getFieldProxy(expression, aBeanTypeProxy, fieldName);
	}
	

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IMethodProxyFactory#getFieldProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String)
	 */
	public IProxyField getFieldProxy(IExpression expression, String className, String fieldName) {
		// We are getting the class resolved through the expression. Might as well because it probably will
		// be needed again and this way when the expression is finished it will be resolved for later usage.
		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fFactoryRegistry.getBeanTypeProxyFactory();
		IProxyBeanType beanType = beanTypeProxyFactory.getBeanTypeProxy(expression, className);
		return beanType.getFieldProxy(expression, fieldName);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.proxy.core.IMethodProxyFactory#getMethodProxy(org.eclipse.jem.internal.proxy.core.IExpression, java.lang.String, java.lang.String, java.lang.String[])
	 */
	public IProxyMethod getMethodProxy(IExpression expression, String className, String methodName, String[] parameterTypes) {
		// We are getting the class and parmtypes resolved through the expression. Might as well because they probably will
		// be needed again and this way when the expression is finished they will be resolved for later usage.
		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fFactoryRegistry.getBeanTypeProxyFactory();
		IProxyBeanType beanType = beanTypeProxyFactory.getBeanTypeProxy(expression, className);
		IProxyBeanType[] parmTypes = getParameterTypes(expression, parameterTypes, beanTypeProxyFactory);
		return beanType.getMethodProxy(expression, methodName, parmTypes);
	}
	
	/**
	 * Helper method for BeanTypes and proxy Beantypes. So they don't need to have common code to convert string to proxy bean type.
	 * @param expression
	 * @param classType
	 * @param methodName
	 * @param parameterTypes
	 * @return
	 * 
	 * @since 1.1.0
	 */
	public IProxyMethod getMethodProxy(IExpression expression, IProxyBeanType classType, String methodName, String[] parameterTypes) {
		// We are getting the class and parmtypes resolved through the expression. Might as well because they probably will
		// be needed again and this way when the expression is finished they will be resolved for later usage.
		IStandardBeanTypeProxyFactory beanTypeProxyFactory = fFactoryRegistry.getBeanTypeProxyFactory();
		IProxyBeanType[] parmTypes = getParameterTypes(expression, parameterTypes, beanTypeProxyFactory);
		return classType.getMethodProxy(expression, methodName, parmTypes);
	}

	/**
	 * @param expression
	 * @param parameterTypes
	 * @param beanTypeProxyFactory
	 * @return
	 * 
	 * @since 1.1.0
	 */
	protected IProxyBeanType[] getParameterTypes(IExpression expression, String[] parameterTypes, IStandardBeanTypeProxyFactory beanTypeProxyFactory) {
		IProxyBeanType[] parmTypes;
		if (parameterTypes == null || parameterTypes.length == 0)
			parmTypes = null;
		else {
			parmTypes = new IProxyBeanType[parameterTypes.length];
			for (int i = 0; i < parameterTypes.length; i++) {
				parmTypes[i] = beanTypeProxyFactory.getBeanTypeProxy(expression, parameterTypes[i]);
			}
		}
		return parmTypes;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jem.internal.proxy.core.IMethodProxyFactory#getInvokable(java.lang.String, java.lang.String, java.lang.String[])
	 */
	public IInvokable getInvokable(String className, String methodName, String[] parameterTypes) {
		IStandardBeanTypeProxyFactory typeFactory = fFactoryRegistry.getBeanTypeProxyFactory();
		IBeanTypeProxy clsProxy = typeFactory.getBeanTypeProxy(className);
		if (clsProxy == null)
			return null;
		return clsProxy.getInvokable(methodName, parameterTypes);
	}

	/**
	 * Get the method id from the remote system and create the method proxy.
	 * 
	 * NOTE: It is public ONLY so that IBeanTypeProxy implementations can call it. It must not be used by anyone else.
	 * 
	 * @param beanType
	 * @param methodName
	 * @param parameterTypes
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public IInvokable getInvokable(IREMBeanTypeProxy beanType, String methodName, String[] parameterTypes) {
		// First convert the parameter types into IBeanTypeProxy[].
		IREMBeanTypeProxy[] types = null;
		if (parameterTypes != null) {
			IStandardBeanTypeProxyFactory typeFactory = fFactoryRegistry.getBeanTypeProxyFactory();
			types = new IREMBeanTypeProxy[parameterTypes.length];
			for (int i = 0; i < parameterTypes.length; i++) {
				IBeanTypeProxy type = types[i] = (IREMBeanTypeProxy) typeFactory.getBeanTypeProxy(parameterTypes[i]);
				if (type == null)
					return null; // One of the parm types doesn't exist.
			}
		}

		return getInvokable(beanType, methodName, types);		
	}
	
	/**
	 * Get the method id from the remote system and create the method proxy.
	 * This does not go through the method cache. It goes direct to the remote vm.
	 * 
	 * NOTE: It is public ONLY so that IBeanTypeProxy implementations can call it. It must not be used by anyone else.
	 */
	public IMethodProxy getMethodProxy(IREMBeanTypeProxy beanType, String methodName, String[] parameterTypes) {
		// First convert the parameter types into IBeanTypeProxy[].
		IBeanTypeProxy[] types = null;
		if (parameterTypes != null) {
			IStandardBeanTypeProxyFactory typeFactory = fFactoryRegistry.getBeanTypeProxyFactory();
			types = new IBeanTypeProxy[parameterTypes.length];
			for (int i = 0; i < parameterTypes.length; i++) {
				IBeanTypeProxy type = types[i] = typeFactory.getBeanTypeProxy(parameterTypes[i]);
				if (type == null)
					return null; // One of the parm types doesn't exist.
			}
		}

		return getMethodProxy(beanType, methodName, types);
	}

	
	/**
	 * Get the invokable. 
	 * 
	 * NOTE: It is public ONLY so that IBeanTypeProxy implementations can call it. It must not be used by anyone else.
	 * @param beanType
	 * @param methodName
	 * @param parameterTypes
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public IInvokable getInvokable(IREMBeanTypeProxy beanType, String methodName, IBeanTypeProxy[] parameterTypes) {
		return new REMInvokable(beanType, methodName, parameterTypes);
	}
	
	/**
	 * Get the method id from the remote system and create the method proxy.
	 * <p>
	 * This does not go through the method cache. It goes direct to the remote vm.
	 * 
	 * NOTE: It is public ONLY so that IBeanTypeProxy implementations can call it. It must not be used by anyone else.
	 */
	public IMethodProxy getMethodProxy(IREMBeanTypeProxy beanType, String methodName, IBeanTypeProxy[] parameterTypes) {
		// The parms to getMethod are:
		// parm[0] = String - method name
		// parm[1] = Class[] - Parameter Classes.
		Object[] parms = new Object[] { methodName, parameterTypes != null ? (new TransmitableArray(Commands.CLASS_CLASS, parameterTypes)) : null};
		IBeanProxy result = null;
		try {
			result = getMethodProxy.invokeWithParms(beanType, parms);
			return (IMethodProxy) result;
		} catch (ThrowableProxy e) {
			fFactoryRegistry.releaseProxy(e); // Since it's not needed, get rid of now instead of GC time.
			return null;
		} catch (ClassCastException e) {
			// Some trace msgs because we keep getting into a mode after awhile (though not reproducible) that returns non-method proxies and we need
			// more info.
			StringBuffer buf = new StringBuffer("Method requested is \"" + methodName + "("); //$NON-NLS-1$	//$NON-NLS-2$
			for (int i = 0; i < parameterTypes.length; i++) {
				if (i > 0)
					buf.append(','); //$NON-NLS-1$
				buf.append(parameterTypes[i].getTypeName());
			}
			buf.append(")\""); //$NON-NLS-1$
			ProxyPlugin.getPlugin().getLogger().log(
					new Status(IStatus.ERROR, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, buf.toString(), null));
			try {
				if (result != null) {
					ProxyPlugin.getPlugin().getLogger().log(
							new Status(IStatus.ERROR, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0,
									"ClassCastException of result. Return type is \"" + result.getTypeProxy().getTypeName() + "\"\n" + //$NON-NLS-1$	//$NON-NLS-2$
											"Return type bean type proxy class=\"" + result.getTypeProxy().getClass().getName() + "\"\n" + //$NON-NLS-1$	//$NON-NLS-2$
											"GetMethodProxy valid=" + getMethodProxy.isValid() + "\n" + //$NON-NLS-1$	//$NON-NLS-2$
											"GetMethodProxy real name is \"" + getMethodProxy.getName() + "\"\n", null)); //$NON-NLS-1$	//$NON-NLS-2$			
				}
			} catch (Exception e2) {
				ProxyPlugin.getPlugin().getLogger().log(new Status(IStatus.ERROR, ProxyPlugin.getPlugin().getBundle().getSymbolicName(), 0, "", e2)); //$NON-NLS-1$
			}
			throw e; // Rethrow it.
		}
	}

	/*
	 * Terminate the factory. Don't need to do anything because of the proxies being held onto are registered any will be cleaned up themselves.
	 */
	public void terminateFactory(boolean wait) {
	}

}
