/*******************************************************************************
 * Copyright (c) 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: ExpressionProcesserController.java,v $
 *  $Revision: 1.5 $  $Date: 2005/02/15 22:57:54 $ 
 */
package org.eclipse.jem.internal.proxy.vm.remote;

import java.io.DataInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.List;

import org.eclipse.jem.internal.proxy.common.*;
import org.eclipse.jem.internal.proxy.common.CommandException;
import org.eclipse.jem.internal.proxy.common.MapTypes;
import org.eclipse.jem.internal.proxy.common.remote.Commands;
import org.eclipse.jem.internal.proxy.common.remote.ExpressionCommands;
import org.eclipse.jem.internal.proxy.initParser.EvaluationException;
import org.eclipse.jem.internal.proxy.initParser.tree.ExpressionProcesser;
import org.eclipse.jem.internal.proxy.initParser.tree.IInternalExpressionConstants;
import org.eclipse.jem.internal.proxy.initParser.tree.IExpressionConstants.NoExpressionValueException;

 
/**
 * This processes the commands for expression processing and sends them over
 * to the common expression processer.
 * 
 * This will be instantiated on the start of an expression. And then
 * each expression request from the IDE will be sent into here. The
 * reason this guy doesn't hold onto the connection and process the
 * entire expression is because we need to return to the connection
 * handler to keep the connection live (there is timeouts and stuff
 * in there that we don't want to duplicate here).
 * <p>
 * If there are any expression processing errors (versus hard io errors) we
 * will save up the error but don't do any more processing other than to make
 * sure we read the complete subcommand. This is so that the inputstream is left
 * in a valid state without standed data.
 * <p>
 * The at the sync point (either get value or sync subcommand) we will send back
 * the error.
 *  
 * @since 1.0.0
 */
public class ExpressionProcesserController {

	protected final RemoteVMServerThread server;
	protected final ConnectionHandler connHandler;	
	protected final ExpressionProcesser exp;
	protected Commands.ValueObject workerValue = new Commands.ValueObject();	// A worker value object so we don't need to keep creating them and releasing them.
	private ClassLoader classLoader;
	
	/**
	 * An error has occurred. At this point all subcommands will simply make sure they flush the input stream
	 * correctly, but they do not process it.
	 * 
	 * @since 1.0.0
	 */
	protected boolean errorOccurred = false;
	
	private String novalueMsg = null;	// If NoExpressionValueException then this is the msg. 
	private Throwable exception = null;	// Was there another kind of exception that was caught.
	
	/**
	 * Create with a default expression processer.
	 * @param server
	 * 
	 * @since 1.0.0
	 */
	public ExpressionProcesserController(RemoteVMServerThread server, ConnectionHandler connHandler) {
		this(server, connHandler, new ExpressionProcesser());
	}
	
	/**
	 * Create from a subclass with a given expression processer.
	 * 
	 * @param server
	 * @param exp
	 * 
	 * @since 1.0.0
	 */
	protected ExpressionProcesserController(RemoteVMServerThread server, ConnectionHandler connHandler, ExpressionProcesser exp) {
		this.server = server;
		this.connHandler = connHandler;
		this.exp = exp;
	}
	
	/**
	 * Set the class loader to use for finding classes. If never set, or if <code>null</code>, then
	 * <code>Class.forName</code> will be used.
	 * 
	 * @param classLoader
	 * 
	 * @since 1.0.0
	 */
	public void setClassLoader(ClassLoader classLoader) {
		this.classLoader = classLoader;
	}
	
	/*
	 * Array of primitive type names. Used to look up primtive types in primitive types array. 
	 * 
	 * @since 1.0.0
	 */
	private static final List PRIMITIVE_NAMES = Arrays.asList(new String[] {"byte", "char", "short", "int", "long", "float", "double"});
	private static final Class[] PRIMITIVE_TYPES = new Class[] {Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE};
	/**
	 * Load the class given the name. If not found, return null.
	 * 
	 * @param className
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected Class loadClass(String className) throws ClassNotFoundException {
		if (className == null)
			return null;
		else if (className.endsWith("[]")) {
			// We have an array request instead. This is trickier.
			return loadClass(MapTypes.getJNIFormatName(className));
		} else {
			int primIndex = PRIMITIVE_NAMES.indexOf(className);
			if (primIndex >= 0)
				return PRIMITIVE_TYPES[primIndex];
			else if (classLoader == null) {
				return Class.forName(className);
			} else {
				return classLoader.loadClass(className);
			}
		}
	}

	/**
	 * Now process the input stream. If either throws occurs, this is a hard error and we must terminate
	 * the entire connection. The input stream is in an unknown state.
	 * 
	 * @param in The input stream to get the data for the current sub-command.
	 * 
	 * @throws CommandException
	 * @throws IOException
	 * @since 1.0.0
	 */
	public void process(DataInputStream in) throws CommandException, IOException {
		// In the following subcommand processing, we always read the entire subcommand from the stream.
		// Then we check if an error has occurred in the past. If it has, we simply break. This is because
		// once an error occurred we don't want to continue wasting time evaluating, however we need to make
		// sure that the stream is read completely so that we don't have a corrupted input stream. That way
		// when all is done we can return the error and still have a valid connection socket.
		byte subcommand = in.readByte();
		try {
			switch (subcommand) {
				case IInternalExpressionConstants.PUSH_TO_PROXY_EXPRESSION :
					// Getting a proxy push. The value is sent as valueObject, so use that to read it in.
					Commands.readValue(in, workerValue);
					if (errorOccurred)
						break;
					Object value = connHandler.getInvokableObject(workerValue);
					if (value == null)
						exp.pushExpression(null, MethodHelper.NULL_TYPE);
					else if (workerValue.isPrimitive())
						exp.pushExpression(value, workerValue.getPrimitiveType());
					else
						exp.pushExpression(value, value.getClass());
					break;

				case IInternalExpressionConstants.CAST_EXPRESSION :
					// Get a cast request. The type is sent as valueObject.
					Commands.readValue(in, workerValue);
					if (errorOccurred)
						break;
					value = connHandler.getInvokableObject(workerValue);
					try {
						if (value instanceof String)
							value = loadClass((String) value);
						exp.pushCast((Class) value);
					} catch (NoExpressionValueException e) {
						processException(e);
					} catch (ClassNotFoundException e) {
						processException(e);
					}
					break;

				case IInternalExpressionConstants.INSTANCEOF_EXPRESSION :
					// Get a instanceof request. The type is sent as valueObject.
					Commands.readValue(in, workerValue);
					if (errorOccurred)
						break;
					value = connHandler.getInvokableObject(workerValue);
					try {
						if (value instanceof String)
							value = loadClass((String) value);
						exp.pushInstanceof((Class) value);
					} catch (ClassNotFoundException e) {
						processException(e);
					} catch (NoExpressionValueException e) {
						processException(e);
					}
					break;

				case IInternalExpressionConstants.INFIX_EXPRESSION :
					// Get an infix request. The operator and operand type are sent as bytes.
					byte infix_operator = in.readByte();
					byte infix_operandType = in.readByte();
					if (errorOccurred)
						break;
					try {
						exp.pushInfix(infix_operator, infix_operandType);
					} catch (NoExpressionValueException e1) {
						processException(e1);
					}
					break;

				case IInternalExpressionConstants.PREFIX_EXPRESSION :
					// Get a prefix request. The operator is sent as byte.
					byte prefix_operandType = in.readByte();
					if (errorOccurred)
						break;
					try {
						exp.pushPrefix(prefix_operandType);
					} catch (NoExpressionValueException e2) {
						processException(e2);
					}
					break;

				case IInternalExpressionConstants.TYPELITERAL_EXPRESSION :
					// Get a type literal request. The type string is sent as valueObject.
					Commands.readValue(in, workerValue);
					if (errorOccurred)
						break;
					value = connHandler.getInvokableObject(workerValue);
					try {
						value = loadClass((String) value);
						exp.pushExpression((Class) value, Class.class);
					} catch (ClassNotFoundException e) {
						processException(e);
					}
					break;

				case IInternalExpressionConstants.ARRAY_ACCESS_EXPRESSION :
					// Get an array access request. The index cound is sent as int.
					int arrayAccess_Indexcount = in.readInt();
					if (errorOccurred)
						break;
					try {
						exp.pushArrayAccess(arrayAccess_Indexcount);
					} catch (NoExpressionValueException e3) {
						processException(e3);
					}
					break;

				case IInternalExpressionConstants.ARRAY_CREATION_EXPRESSION :
					// Get an array creation request. The type is sent as valueObject, followed by int dimension count.
					Commands.readValue(in, workerValue);
					int arrayCreation_dimCount = in.readInt();
					if (errorOccurred)
						break;
					value = connHandler.getInvokableObject(workerValue);
					try {
						if (value instanceof String)
							value = loadClass((String) value);
						exp.pushArrayCreation((Class) value, arrayCreation_dimCount);
					} catch (ClassNotFoundException e) {
						processException(e);
					} catch (NoExpressionValueException e) {
						processException(e);
					}
					break;

				case IInternalExpressionConstants.ARRAY_INITIALIZER_EXPRESSION :
					// Get an array initializer request. The type is sent as valueObject, followed by int expression count.
					Commands.readValue(in, workerValue);
					int arrayInitializer_expressionCount = in.readInt();
					if (errorOccurred)
						break;
					value = connHandler.getInvokableObject(workerValue);
					try {
						if (value instanceof String)
							value = loadClass((String) value);
						exp.pushArrayInitializer((Class) value, arrayInitializer_expressionCount);
					} catch (ClassNotFoundException e) {
						processException(e);
					} catch (NoExpressionValueException e) {
						processException(e);
					}
					break;

				case IInternalExpressionConstants.CLASS_INSTANCE_CREATION_EXPRESSION :
					// Get a class instance creation request. The type is sent as valueObject, followed by int argument count.
					Commands.readValue(in, workerValue);
					int newInstance_argCount = in.readInt();
					if (errorOccurred)
						return;
					value = connHandler.getInvokableObject(workerValue);
					try {
						if (value instanceof String)
							value = loadClass((String) value);
						exp.pushClassInstanceCreation((Class) value, newInstance_argCount);
					} catch (ClassNotFoundException e) {
						processException(e);
					} catch (EvaluationException e) {
						processException(e);
					} catch (NoExpressionValueException e) {
						processException(e);
					} catch (InstantiationException e) {
						processException(e);
					} catch (IllegalAccessException e) {
						processException(e);
					} catch (InvocationTargetException e) {
						processException(e);
					} catch (LinkageError e) {
						processError(e);
					}
					break;

				case IInternalExpressionConstants.TYPERECEIVER_EXPRESSION :
					// Get a type receiver request. The type is sent as valueObject.
					Commands.readValue(in, workerValue);
					if (errorOccurred)
						break;
					value = connHandler.getInvokableObject(workerValue);
					try {
						if (value instanceof String)
							value = loadClass((String) value);
						exp.pushExpression(value, (Class) value);
					} catch (ClassNotFoundException e) {
						processException(e);
					}
					break;

				case IInternalExpressionConstants.FIELD_ACCESS_EXPRESSION :
					// Get a field access request. The field name sent as string, followed by hasReceiver as boolean.
					String fieldAccess_name = in.readUTF();
					boolean fieldAccess_receiver = in.readBoolean();
					if (errorOccurred)
						break;
					try {
						exp.pushFieldAccess(fieldAccess_name, fieldAccess_receiver);
					} catch (NoExpressionValueException e4) {
						processException(e4);
					} catch (NoSuchFieldException e4) {
						processException(e4);
					} catch (IllegalAccessException e4) {
						processException(e4);
					}
					break;

				case IInternalExpressionConstants.METHOD_EXPRESSION :
					// Get a method invocation request. The method name sent as string, followed by hasReceiver as boolean, and argCount as int.
					String method_name = in.readUTF();
					boolean method_receiver = in.readBoolean();
					int method_argCount = in.readInt();
					if (errorOccurred)
						break;
					try {
						exp.pushMethodInvocation(method_name, method_receiver, method_argCount);
					} catch (EvaluationException e5) {
						processException(e5);
					} catch (NoExpressionValueException e5) {
						processException(e5);
					} catch (IllegalAccessException e5) {
						processException(e5);
					} catch (InvocationTargetException e5) {
						processException(e5);
					}
					break;

				case IInternalExpressionConstants.CONDITIONAL_EXPRESSION :
					// Get a conditional expression request. The expression type (ie. condition/true/false) is sent as a byte
					byte conditional_type = in.readByte();
					if (errorOccurred)
						break;
					try {
						exp.pushConditional(conditional_type);
					} catch (NoExpressionValueException e6) {
						processException(e6);
					}
					break;
			}
			
		} catch (RuntimeException e) {
			processException(e);
		}
		
		workerValue.set();	// Clear it out so nothing being held onto.
	}
	

	/**
	 * Pull the value. If an error occurred during this, then <code>null</code> is returned, and
	 * caller should do normal error processing.
	 * 
	 * @return r[0] is the value, r[1] is the type of the value. <code>null</code> if there was an error.
	 * 
	 * @since 1.0.0
	 */
	public Object[] pullValue() {
		Object[] result = new Object[2];
		try {
			exp.pullValue(result);
			return result;
		} catch (NoExpressionValueException e) {
			processException(e);
		}
		return null;
	}
	
	/**
	 * Process all other exceptions then the NoExpressionValueException, InvocationTargetException, and EvaluationException. This is
	 * for exceptions that are not related to the input stream and shouldn't
	 * cause the input stream to be closed.
	 * 
	 * @param e
	 * 
	 * @since 1.0.0
	 */
	protected final void processException(Exception e) {
		// Process all other exceptions.
		errorOccurred = true;
		exception = e;
	}
	
	/**
	 * Process certain errors. Should not be called for general errors. Should be called for specific java.lang.Errors that
	 * are not related to the input stream and shouldn't cause the input stream to be closed.
	 *  
	 * @param e
	 * 
	 * @since 1.0.2
	 */
	protected final void processError(Error e) {
		// Process specific errors
		errorOccurred = true;
		exception = e;		
	}
	
	/**
	 * Process InvocationTargetException to retrieve the actual target.
	 * @param e
	 * 
	 * @since 1.0.0
	 */
	protected final void processException(InvocationTargetException e) {
		errorOccurred = true;
		exception = e.getTargetException();
	}
	
	/**
	 * Process EvaluationException to retrieve the actual target.
	 * @param e
	 * 
	 * @since 1.0.0
	 */
	protected final void processException(EvaluationException e) {
		errorOccurred = true;
		exception = e.getOriginalException();
	}	

	/**
	 * Special case for NoExpressionValueException caught.
	 * @param e
	 * 
	 * @since 1.0.0
	 */
	protected final void processException(NoExpressionValueException e) {
		errorOccurred = true;
		novalueMsg = e.getLocalizedMessage();
		if (novalueMsg == null)
			novalueMsg = "";	// It was null, so just default of empty string so we know it had occurred.
	}

	/**
	 * Return whether there are any errors.
	 * 
	 * @return <code>true</code> if no errors.
	 * 
	 * @since 1.0.0
	 */
	public boolean noErrors() {
		return !errorOccurred;
	}
	
	/**
	 * Return the error code from ExpressionCommands if non-exception error occurred.
	 * Return zero if no error.
	 * 
	 * @return Zero if no error code to return, else error code from ExpressionCommands.
	 * 
	 * @see org.eclipse.jem.internal.proxy.common.remote.ExpressionCommands#ExpressionNoExpressionValueException
	 * 
	 * @since 1.0.0
	 */
	public int getErrorCode() {
		if (novalueMsg != null)
			return ExpressionCommands.ExpressionNoExpressionValueException;
		else
			return 0;
	}
	
	/**
	 * Return the error message, should only be called if <code>getErrorCode()</code> returned non-zero.
	 * 
	 * @return The error message if any. <code>null</code> otherwise.
	 * 
	 * @since 1.0.0
	 */
	public String getErrorMsg() {
		if (novalueMsg != null && novalueMsg.length() > 0)
			return novalueMsg;
		else
			return null;
	}
	
	/**
	 * Return the throwable if a Throwable was caught.
	 * 
	 * @return The throwable, or <code>null</code> if not set.
	 * 
	 * @since 1.0.0
	 */
	public Throwable getErrorThrowable() {
		return exception;
	}
	
	/**
	 * Close out things.
	 * 
	 * @since 1.0.0
	 */
	public void close() {
		exp.close();
	}

}
