/****************************************************************************
 * Copyright (c) 2004 Composent, Inc. 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:
 *    Composent, Inc. - initial API and implementation
 *****************************************************************************/

package org.eclipse.ecf.example.collab.share;

import java.io.NotSerializableException;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

import org.eclipse.core.runtime.Assert;
import org.eclipse.ecf.core.identity.ID;
import org.eclipse.ecf.internal.example.collab.Messages;
import org.eclipse.osgi.util.NLS;

public class SharedObjectMsg implements Serializable {
	static final long serialVersionUID = 571132189626558278L;
	public static final Object[] nullArgs = new Object[0];
	public static final Class[] nullTypes = new Class[0];

	class SenderID {

		private final ID id;

		// No instances other than ones created in SharedObjectMsg.invokeFrom/2
		protected SenderID(ID theID) {
			id = theID;
		}

		public ID getID() {
			return id;
		}
	}

	// Static factory methods for creating SharedObjectMsg instances
	public static SharedObjectMsg createMsg(String className, String methodName, Object[] param) {
		Assert.isNotNull(methodName);
		Assert.isNotNull(param);
		return new SharedObjectMsg(className, methodName, param);
	}

	public static SharedObjectMsg createMsg(String methodName, Object[] param) {
		return createMsg((String) null, methodName, param);
	}

	public static SharedObjectMsg createMsg(String methodName) {
		return createMsg((String) null, methodName, nullArgs);
	}

	public static SharedObjectMsg createMsg(String className, String methodName) {
		return createMsg(className, methodName, nullArgs);
	}

	public static SharedObjectMsg createMsg(String className, String methodName, Object arg) {
		final Object args[] = {arg};
		return createMsg(className, methodName, args);
	}

	public static SharedObjectMsg createMsg(String methodName, Object arg) {
		return createMsg((String) null, methodName, arg);
	}

	public static SharedObjectMsg createMsg(String className, String methodName, Object arg1, Object arg2) {
		final Object args[] = {arg1, arg2};
		return createMsg(className, methodName, args);
	}

	public static SharedObjectMsg createMsg(String className, String methodName, Object arg1, Object arg2, Object arg3) {
		final Object args[] = {arg1, arg2, arg3};
		return createMsg(className, methodName, args);
	}

	public static SharedObjectMsg createMsg(String className, String methodName, Object arg1, Object arg2, Object arg3, Object arg4) {
		final Object args[] = {arg1, arg2, arg3, arg4};
		return createMsg(className, methodName, args);
	}

	public static SharedObjectMsg createMsg(String className, String methodName, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {
		final Object args[] = {arg1, arg2, arg3, arg4, arg5};
		return createMsg(className, methodName, args);
	}

	/**
	 * Utility for getting a Class instance from a String class name. Calls
	 * Class.forName().
	 * 
	 * @param loader
	 *            the ClassLoader to use to load the given class
	 * @param name
	 *            of Class to load
	 * @return Class instance found. If not found, a ClassNotFoundException is
	 *         thrown
	 * @exception ClassNotFoundException
	 *                thrown if specified class is not found
	 */
	public static Class getClass(ClassLoader loader, String name) throws ClassNotFoundException {
		if (name == null)
			return null;
		return Class.forName(name, true, loader);
	}

	/**
	 * Get name for given class.
	 * 
	 * @param clazz
	 *            the Class to retrieve the name from
	 * @return String name of given class
	 */
	public static String getName(Class clazz) {
		return clazz.getName();
	}

	/**
	 * Get array of argument types from array of objects
	 * 
	 * @param args
	 *            the arguments to get types for
	 * @return Class[] of types for objects in given Object array
	 */
	public static Class[] getArgTypes(Object args[]) {
		Class argTypes[] = null;
		if (args == null || args.length == 0)
			argTypes = nullTypes;
		else {
			argTypes = new Class[args.length];
			for (int i = 0; i < args.length; i++) {
				if (args[i] == null)
					argTypes[i] = null;
				else
					argTypes[i] = args[i].getClass();
			}
		}
		return argTypes;
	}

	/**
	 * Find a Method instance on given class. This method searches for a method
	 * on the given class (first parameter), of the given name (second
	 * parameter), and of arity defined by the third parameter. Calls
	 * searchForMethod to actually do the searching.
	 * 
	 * @param clazz
	 *            the Class to look on
	 * @param meth
	 *            the method name to look for
	 * @param args
	 *            the arguments that will be passed to the method on the invoke
	 *            call
	 * @return Method instance found on given class. Null if none found.
	 */
	static Method findMethod(final Class clazz, String meth, Class args[]) {
		Method methods[] = null;
		try {
			methods = (Method[]) AccessController.doPrivileged(new PrivilegedExceptionAction() {
				public Object run() throws Exception {
					return clazz.getDeclaredMethods();
				}
			});
		} catch (final PrivilegedActionException e) {
			return null;
		}
		return searchForMethod(methods, meth, args);
	}

	public static Method searchForMethod(Method meths[], String meth, Class args[]) {
		// Find it from among the given set of Method objects
		for (int i = 0; i < meths.length; i++) {
			final Method test = meths[i];
			if (test.getName().equals(meth)) {
				if (test.getParameterTypes().length == args.length)
					return test;
			}
		}
		return null;
	}

	/**
	 * Find a Method instance on given class, and recursively search the class'
	 * superclass tree for given method.
	 * 
	 * @param clazz
	 *            the Class to look upon
	 * @param meth
	 *            the String name of the method to look for
	 * @param args
	 *            the array of Object arguments that will be passed to the
	 *            method for execution
	 * @return Method instance if found, null if not found
	 */
	public static Method findMethodRecursive(Class clazz, String meth, Class args[]) {
		final Method aMethod = findMethod(clazz, meth, args);
		if (aMethod == null) {
			final Class superclazz = clazz.getSuperclass();
			if (superclazz != null)
				return findMethodRecursive(superclazz, meth, args);
			else
				return null;
		} else {
			return aMethod;
		}
	}

	/**
	 * Check a given msg to verify that all Objects in args array implement the
	 * Serializable interface.
	 * 
	 * @param aMsg
	 *            the Message to check
	 * @exception NotSerializableException
	 *                thrown if any objects in args array do not implement the
	 *                Serializable interface
	 */
	public static void checkForSerializable(SharedObjectMsg aMsg) throws NotSerializableException {
		final Object args[] = aMsg.getArgs();
		for (int i = 0; i < args.length; i++) {
			if (args[i] != null && !(args[i] instanceof Serializable))
				throw new NotSerializableException(NLS.bind(Messages.SharedObjectMsg_EXCEPTION_NOT_SERIALIZABLE, new Integer(i)));
		}
	}

	// Instance fields
	/**
	 * @serial myClassName the class name for the message
	 */
	String myClassName;
	/**
	 * @serial myMethodName the method name of the message
	 */
	String myMethodName;
	/**
	 * @serial myArgs arguments
	 */
	Object[] myArgs;

	// Constructor
	SharedObjectMsg(String className, String methodName, Object[] args) {
		myClassName = className;
		myMethodName = methodName;
		myArgs = args;
	}

	/**
	 * Constructor for TypedMsg's.
	 */
	SharedObjectMsg(String methodName) {
		this(null, methodName, null);
	}

	public final String getMethodName() {
		return myMethodName;
	}

	public final void setMethodName(String name) {
		checkAlterMsg();
		if (name == null)
			throw new NullPointerException(Messages.SharedObjectMsg_EXCEPTION_METHOD_NOT_NULL);
		myMethodName = name;
	}

	/**
	 * Check if it is permitted to alter the state of this message (args, class
	 * name, method name). Default: NOP; subclasses should override as
	 * appropriate. To disallow, throw a java.lang.RuntimeException.
	 */
	protected void checkAlterMsg() {
		// NOP; subclasses should override as appropriate
	}

	public final String getClassName() {
		return myClassName;
	}

	public final void setClassName(String name) {
		checkAlterMsg();
		myClassName = name;
	}

	public Object[] getArgs() // TypedMsg overrides
	{
		return myArgs;
	}

	public final void setArgs(Object[] args) {
		checkAlterMsg();
		myArgs = (args == null) ? nullArgs : args;
	}

	protected Class[] getArgTypes() {
		return getArgTypes(getArgs());
	}

	protected final Method findMethod(Class clazz) {
		return findMethod(clazz, getMethodName(), getArgTypes());
	}

	protected final Method findMethodRecursive(Class clazz) {
		return findMethodRecursive(clazz, getMethodName(), getArgTypes());
	}

	public final Object invoke(Object target) throws Exception {
		return doInvoke(target);
	}

	Object doInvoke(final Object target) // package scope for security
			throws Exception {
		if (target == null)
			throw new NoSuchMethodException(Messages.SharedObjectMsg_EXCEPTION_NULL_TARGET);
		Method meth = null;
		if (myClassName == null) {
			// If not specific class is specified by SharedObjectMsg instance,
			// then use the target's class
			meth = findMethodRecursive(target.getClass());
		} else {
			// If it is specified, then load the specified class, using the
			// target object's classloader
			meth = findMethod(getClass(target.getClass().getClassLoader(), myClassName));
		}
		// If no method was found, then throw
		if (meth == null)
			throw new NoSuchMethodException(getMethodName());
		final Method toCall = meth;
		// Make priveleged call to set the method as accessible
		AccessController.doPrivileged(new PrivilegedExceptionAction() {
			public Object run() throws Exception {
				if (!toCall.isAccessible())
					toCall.setAccessible(true);
				return null;
			}
		});
		// Actually invoke method
		return toCall.invoke(target, getArgs());
	}

	public final Object invokeFrom(ID fromID, final Object target) throws Exception {
		// Setup new array of arguments with the fromID on the front
		Object[] newParams = null;
		final SenderID sender = new SenderID(fromID);
		final Object args[] = getArgs();
		if (args == null) {
			newParams = new Object[1];
			newParams[0] = sender;
		} else {
			newParams = new Object[myArgs.length + 1];
			newParams[0] = sender;
			System.arraycopy(args, 0, newParams, 1, args.length);
		}
		// Reset arguments before method search
		myArgs = newParams;
		// Now just call invoke/1
		return invoke(target);
	}

	public String toString() {
		final StringBuffer sb = new StringBuffer();
		sb.append("SharedObjectMsg[").append(myClassName).append(":").append(myMethodName).append("("); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		if (myArgs == null) {
			sb.append(myArgs);
		} else {
			for (int i = 0; i < myArgs.length; i++) {
				if (i > 0)
					sb.append(","); //$NON-NLS-1$
				sb.append(myArgs[i]);
			}
		}
		sb.append(")]"); //$NON-NLS-1$
		return sb.toString();
	}
}
