/*******************************************************************************
 * Copyright (c) 2004, 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 v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
/*


 */
package org.eclipse.jem.internal.instantiation.base;

import java.text.MessageFormat;
import java.util.List;

import org.eclipse.jem.internal.instantiation.*;
import org.eclipse.jem.internal.proxy.core.*;
import org.eclipse.jem.internal.proxy.initParser.tree.*;
 
/**
 * This is the standard parse visitor for instantiating a bean proxy from a java parse tree allocation.
 * It can be reused, but is not thread-safe.
 * 
 * @since 1.0.0
 */
public class ParseTreeAllocationInstantiationVisitor extends ParseVisitor {
		
	/**
	 * The expression that is being created and evaluated.
	 */
	private IExpression expression;
	
	/*
	 * The next expression type that should be used. It is used when one expression is sending the
	 * visitation to the next expression. It will set this to what that expression should be using. This
	 * is necessary because the next expression doesn't know what it should be.
	 */
	private ForExpression nextExpression = ForExpression.ROOTEXPRESSION;
	
	/**
	 * An exception occurred during processing. It is a RuntimeException because
	 * it can be thrown at any time. It wrappers another exception. That exception
	 * can be retrieved from the cause of the ProcessingException.
	 * 
	 * @see Throwable#getCause()
	 * @since 1.0.0
	 */
	public static class ProcessingException extends RuntimeException {
		
		/**
		 * Comment for <code>serialVersionUID</code>
		 * 
		 * @since 1.1.0
		 */
		private static final long serialVersionUID = 1268624222490406643L;

		/**
		 * @param cause
		 * 
		 * @since 1.0.0
		 */
		public ProcessingException(Throwable cause) {
			super(cause);
		}
	}
	
	static final InfixOperator[] INFIXTOPROXY;
	static {
		INFIXTOPROXY = new InfixOperator[PTInfixOperator.VALUES.size()];
		INFIXTOPROXY[PTInfixOperator.AND] = InfixOperator.IN_AND;
		INFIXTOPROXY[PTInfixOperator.CONDITIONAL_AND] = InfixOperator.IN_CONDITIONAL_AND;
		INFIXTOPROXY[PTInfixOperator.CONDITIONAL_OR] = InfixOperator.IN_CONDITIONAL_OR;
		INFIXTOPROXY[PTInfixOperator.DIVIDE] = InfixOperator.IN_DIVIDE;
		INFIXTOPROXY[PTInfixOperator.EQUALS] = InfixOperator.IN_EQUALS;
		INFIXTOPROXY[PTInfixOperator.GREATER] = InfixOperator.IN_GREATER;
		INFIXTOPROXY[PTInfixOperator.GREATER_EQUALS] = InfixOperator.IN_GREATER_EQUALS;
		INFIXTOPROXY[PTInfixOperator.LEFT_SHIFT] = InfixOperator.IN_LEFT_SHIFT;
		INFIXTOPROXY[PTInfixOperator.LESS] = InfixOperator.IN_LESS;
		INFIXTOPROXY[PTInfixOperator.LESS_EQUALS] = InfixOperator.IN_LESS_EQUALS;
		INFIXTOPROXY[PTInfixOperator.MINUS] = InfixOperator.IN_MINUS;
		INFIXTOPROXY[PTInfixOperator.NOT_EQUALS] = InfixOperator.IN_NOT_EQUALS;
		INFIXTOPROXY[PTInfixOperator.OR] = InfixOperator.IN_OR;
		INFIXTOPROXY[PTInfixOperator.PLUS] = InfixOperator.IN_PLUS;
		INFIXTOPROXY[PTInfixOperator.REMAINDER] = InfixOperator.IN_REMAINDER;
		INFIXTOPROXY[PTInfixOperator.RIGHT_SHIFT_SIGNED] = InfixOperator.IN_RIGHT_SHIFT_SIGNED;
		INFIXTOPROXY[PTInfixOperator.RIGHT_SHIFT_UNSIGNED] = InfixOperator.IN_RIGHT_SHIFT_UNSIGNED;
		INFIXTOPROXY[PTInfixOperator.TIMES] = InfixOperator.IN_TIMES;
		INFIXTOPROXY[PTInfixOperator.XOR] = InfixOperator.IN_XOR;
	}
	
	/**
	 * A helper method to convert the parse tree's infix operator to the Proxy infix operator.
	 * 
	 * @param operator
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public static InfixOperator convertPTInfixOperatorToProxyInfixOperator(PTInfixOperator operator) {
		return INFIXTOPROXY[operator.getValue()];
	}

	static final PrefixOperator[] PREFIXTOPROXY;
	static {
		PREFIXTOPROXY = new PrefixOperator[PTPrefixOperator.VALUES.size()];
		PREFIXTOPROXY[PTPrefixOperator.COMPLEMENT] = PrefixOperator.PRE_COMPLEMENT;
		PREFIXTOPROXY[PTPrefixOperator.MINUS] = PrefixOperator.PRE_MINUS;
		PREFIXTOPROXY[PTPrefixOperator.NOT] = PrefixOperator.PRE_NOT;
		PREFIXTOPROXY[PTPrefixOperator.PLUS] = PrefixOperator.PRE_PLUS;
	}
	
	/**
	 * A helper method to convert the parse tree's prefix operator to the Proxy prefix operator.
	 * 
	 * @param operator
	 * @return
	 * 
	 * @since 1.0.0
	 */
	public static PrefixOperator convertPTPrefixOperatorToProxyPrefixOperator(PTPrefixOperator operator) {
		return PREFIXTOPROXY[operator.getValue()];
	}
	
	/**
	 * Create the visitor with the given registry.
	 * 
	 * @param registry
	 * 
	 * @since 1.0.0
	 */
	public ParseTreeAllocationInstantiationVisitor() {
	}
	
	/**
	 * Get the current registry.
	 * 
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final ProxyFactoryRegistry getRegistry() {
		return expression.getRegistry();
	}
	
	/**
	 * Get the current expression.
	 * 
	 * @return
	 * 
	 * @since 1.0.0
	 */
	protected final IExpression getExpression() {
		return expression;
	}	

	/**
	 * Get the beanproxy for the given expression and registry. It will evaluate immediately.
	 * 
	 * @param expression
	 * @param registry
	 * @return
	 * @throws IllegalStateException
	 * @throws ThrowableProxy
	 * @throws NoExpressionValueException
	 * @throws ProcessingException
	 * 
	 * @since 1.0.0
	 */
	public IBeanProxy getBeanProxy(PTExpression expression, ProxyFactoryRegistry registry) throws IllegalStateException, IllegalArgumentException, ThrowableProxy, NoExpressionValueException, ProcessingException {
		this.expression = registry.getBeanProxyFactory().createExpression();
		setNextExpression(ForExpression.ROOTEXPRESSION);
		try {
			expression.accept(this);
		} catch (ProcessingException e) {
			// Handle the most common that make sense to be know distinctly and throw them instead of ProcessingException.
			Throwable t = e.getCause();
			if (t instanceof NoExpressionValueException)
				throw (NoExpressionValueException) t;
			else if (t instanceof IllegalStateException)
				throw (IllegalStateException) t;
			else
				throw e;
		}
		
		return getExpression().getExpressionValue();
	}
	
	/**
	 * Using the given expression processor allocate the proxy. It will not evaluate immediately, but just push onto the expression.
	 * @param expression
	 * @param expressionProcessor
	 * @return the ExpressionProxy for the allocation.
	 * @throws IllegalStateException
	 * @throws IllegalArgumentException
	 * @throws ProcessingException
	 * 
	 * @since 1.1.0
	 */
	public ExpressionProxy getProxy(PTExpression expression, IExpression expressionProcessor) throws IllegalStateException, IllegalArgumentException, ProcessingException {
		this.expression = expressionProcessor;
		try {
			ExpressionProxy proxy = expressionProcessor.createProxyAssignmentExpression(ForExpression.ROOTEXPRESSION);
			setNextExpression(ForExpression.ASSIGNMENT_RIGHT);
			expression.accept(this);
			return proxy;
		} catch (ProcessingException e) {
			// Handle the most common that make sense to be know distinctly and throw them instead of ProcessingException.
			Throwable t = e.getCause();
			if (t instanceof IllegalStateException)
				throw (IllegalStateException) t;
			else
				throw e;
		}
	}

	
	/**
	 * Set the next expression type. (i.e. the <code>forExpression</code> field of most of the create expression methods.
	 * 
	 * @param nextExpression
	 * 
	 * @see IExpression#createInfixExpression(int, int, int)
	 * @since 1.0.0
	 */
	protected final void setNextExpression(ForExpression nextExpression) {
		this.nextExpression = nextExpression;
	}

	/**
	 * Get the next expression type. (i.e. the <code>forExpression</code> field of most of the create expression methods.
	 * 
	 * @return
	 * 
	 * @see IExpression#createInfixExpression(int, int, int)
	 * @since 1.0.0
	 */
	protected final ForExpression getNextExpression() {
		return nextExpression;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTAnonymousClassDeclaration)
	 */
	public boolean visit(PTAnonymousClassDeclaration node) {
		throw new IllegalArgumentException(MessageFormat.format(InstantiationBaseMessages.ParseTreeAllocationInstantiationVisitor_CannotProcessAnonymousDeclarations_EXC_, new Object[] {node.getDeclaration()}));
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTArrayAccess)
	 */
	public boolean visit(PTArrayAccess node) {
		getExpression().createArrayAccess(getNextExpression(), node.getIndexes().size());
		setNextExpression(ForExpression.ARRAYACCESS_ARRAY);
		node.getArray().accept(this);
		List idx = node.getIndexes();
		int s = idx.size();
		for (int i = 0; i < s; i++) {
			setNextExpression(ForExpression.ARRAYACCESS_INDEX);
			((PTExpression) idx.get(i)).accept(this);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTArrayCreation)
	 */
	public boolean visit(PTArrayCreation node) {
		getExpression().createArrayCreation(getNextExpression(), node.getType(), node.getDimensions().size());
		if (node.getDimensions().isEmpty()) {
			node.getInitializer().accept(this);	// Array initializer doesn't require a next expression.
		} else {
			List dims = node.getDimensions();
			int s = dims.size();
			for (int i = 0; i < s; i++) {
				setNextExpression(ForExpression.ARRAYCREATION_DIMENSION);
				((PTExpression) dims.get(i)).accept(this);
			}
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTArrayInitializer)
	 */
	public boolean visit(PTArrayInitializer node) {
		getExpression().createArrayInitializer(node.getExpressions().size());
		List exps = node.getExpressions();
		int s = exps.size();
		for (int i = 0; i < s; i++) {
			setNextExpression(ForExpression.ARRAYINITIALIZER_EXPRESSION);
			((PTExpression) exps.get(i)).accept(this);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTBooleanLiteral)
	 */
	public boolean visit(PTBooleanLiteral node) {
		getExpression().createPrimitiveLiteral(getNextExpression(), node.isBooleanValue());
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTCastExpression)
	 */
	public boolean visit(PTCastExpression node) {
		getExpression().createCastExpression(getNextExpression(), node.getType());
		setNextExpression(ForExpression.CAST_EXPRESSION);
		node.getExpression().accept(this);
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTCharacterLiteral)
	 */
	public boolean visit(PTCharacterLiteral node) {
		getExpression().createPrimitiveLiteral(getNextExpression(), node.getCharValue());
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTClassInstanceCreation)
	 */
	public boolean visit(PTClassInstanceCreation node) {
		getExpression().createClassInstanceCreation(getNextExpression(), node.getType(), node.getArguments().size());
		List args = node.getArguments();
		int s = args.size();
		for (int i = 0; i < s; i++) {
			setNextExpression(ForExpression.CLASSINSTANCECREATION_ARGUMENT);
			((PTExpression) args.get(i)).accept(this);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTConditionalExpression)
	 */
	public boolean visit(PTConditionalExpression node) {
		getExpression().createConditionalExpression(getNextExpression());
		setNextExpression(ForExpression.CONDITIONAL_CONDITION);
		node.getCondition().accept(this);
		setNextExpression(ForExpression.CONDITIONAL_TRUE);
		node.getTrue().accept(this);
		setNextExpression(ForExpression.CONDITIONAL_FALSE);
		node.getFalse().accept(this);
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTFieldAccess)
	 */
	public boolean visit(PTFieldAccess node) {
		getExpression().createFieldAccess(getNextExpression(), node.getField(), node.getReceiver() != null);
		if (node.getReceiver() != null) {
			setNextExpression(ForExpression.FIELD_RECEIVER);
			node.getReceiver().accept(this);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTInfixExpression)
	 */
	public boolean visit(PTInfixExpression node) {
		getExpression().createInfixExpression(getNextExpression(), convertPTInfixOperatorToProxyInfixOperator(node.getOperator()), node.getExtendedOperands().size());
		setNextExpression(ForExpression.INFIX_LEFT);
		node.getLeftOperand().accept(this);
		setNextExpression(ForExpression.INFIX_RIGHT);
		node.getRightOperand().accept(this);
		List extended = node.getExtendedOperands();
		int s = extended.size();
		for (int i = 0; i < s; i++) {
			setNextExpression(ForExpression.INFIX_EXTENDED);
			((PTExpression) extended.get(i)).accept(this);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTInstanceof)
	 */
	public boolean visit(PTInstanceof node) {
		getExpression().createInstanceofExpression(getNextExpression(), node.getType());
		setNextExpression(ForExpression.INSTANCEOF_VALUE);
		node.getOperand().accept(this);
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTInvalidExpression)
	 */
	public boolean visit(PTInvalidExpression node) {
		throw new IllegalArgumentException(node.getMessage());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTMethodInvocation)
	 */
	public boolean visit(PTMethodInvocation node) {
		getExpression().createMethodInvocation(getNextExpression(), node.getName(), node.getReceiver() != null, node.getArguments().size());
		if (node.getReceiver() != null) {
			setNextExpression(ForExpression.METHOD_RECEIVER);
			node.getReceiver().accept(this);
		}
		List args = node.getArguments();
		int s = args.size();
		for (int i = 0; i < s; i++) {
			setNextExpression(ForExpression.METHOD_ARGUMENT);
			((PTExpression) args.get(i)).accept(this);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTName)
	 */
	public boolean visit(PTName node) {
		// This is special in the PTName can only be used as a type receiver at this time.
		getExpression().createTypeReceiver(node.getName());
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTNullLiteral)
	 */
	public boolean visit(PTNullLiteral node) {
		// This is special in the PTName can only be used as a type receiver at this time.
		getExpression().createNull(getNextExpression());
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTNumberLiteral)
	 */
	public boolean visit(PTNumberLiteral node) {
		// It is assumed the tokens are trimmed.
		String lit = node.getToken();
		char lastChar = lit.charAt(lit.length()-1);
		if (lastChar == 'l' || lastChar == 'L' ) {
			// It is definitely a long.
			// Using decode so that things like 0x3 will be parsed. parseLong won't recognize those.
			getExpression().createPrimitiveLiteral(getNextExpression(), Long.decode(lit.substring(0, lit.length()-1)).longValue());
		} else if (lastChar == 'F' || lastChar == 'f') {
			// It is definitely a float.
			getExpression().createPrimitiveLiteral(getNextExpression(), Float.parseFloat(lit.substring(0, lit.length()-1)));
		} else if (lastChar == 'D' || lastChar == 'd')  {
			// It is definitely a double.
			getExpression().createPrimitiveLiteral(getNextExpression(), Double.parseDouble(lit.substring(0, lit.length()-1)));
		} else if (lit.indexOf('.') != -1 || lit.indexOf('e') != -1 || lit.indexOf('E') != -1) {
				// It is definitely a double. (has a period or an exponent, but does not have an 'f' on the end is always a double).
				getExpression().createPrimitiveLiteral(getNextExpression(), Double.parseDouble(lit.substring(0, lit.length())));
		} else {
			// Using decode so that things like 0x3 will be parsed. parseInt won't recognize those.
			getExpression().createPrimitiveLiteral(getNextExpression(), Integer.decode(lit).intValue());
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTParenthesizedExpression)
	 */
	public boolean visit(PTParenthesizedExpression node) {
		node.getExpression().accept(this);	// For instantiation purposes, the parenthesis can be ignored.
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTPrefixExpression)
	 */
	public boolean visit(PTPrefixExpression node) {
		getExpression().createPrefixExpression(getNextExpression(), convertPTPrefixOperatorToProxyPrefixOperator(node.getOperator()));
		setNextExpression(ForExpression.PREFIX_OPERAND);
		node.getExpression().accept(this);
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTStringLiteral)
	 */
	public boolean visit(PTStringLiteral node) {
		getExpression().createProxyExpression(getNextExpression(), getRegistry().getBeanProxyFactory().createBeanProxyWith(node.getLiteralValue()));
		return false;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTThisLiteral)
	 */
	public boolean visit(PTThisLiteral node) {
		throw new IllegalArgumentException(InstantiationBaseMessages.ParseTreeAllocationInstantiationVisitor_CurrentlyThisNotSupported_EXC_); 
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jem.internal.instantiation.ParseVisitor#visit(org.eclipse.jem.internal.instantiation.PTTypeLiteral)
	 */
	public boolean visit(PTTypeLiteral node) {
		getExpression().createTypeLiteral(getNextExpression(), node.getType());
		return false;
	}

}
