/*******************************************************************************
 * Copyright (c) 2011, 2015 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
 *     Nikolay Metchev <nikolaymetchev@gmail.com> - [inline] Inline local variable with initializer generates assignment where left-hand side is not a variable - https://bugs.eclipse.org/394721
 *******************************************************************************/

package org.eclipse.jdt.internal.corext.dom;

import java.util.Iterator;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ArrayAccess;
import org.eclipse.jdt.core.dom.ArrayCreation;
import org.eclipse.jdt.core.dom.AssertStatement;
import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
import org.eclipse.jdt.core.dom.ConditionalExpression;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.InfixExpression.Operator;
import org.eclipse.jdt.core.dom.ParenthesizedExpression;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.ReturnStatement;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor;
import org.eclipse.jdt.core.dom.SwitchCase;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.SynchronizedStatement;
import org.eclipse.jdt.core.dom.ThrowStatement;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.WhileStatement;

import org.eclipse.jdt.internal.corext.refactoring.code.OperatorPrecedence;
import org.eclipse.jdt.internal.corext.util.JDTUIHelperClasses;

/**
 * Helper class to check if an expression requires parentheses.
 * 
 * @see JDTUIHelperClasses
 * @since 3.7
 */
public class NecessaryParenthesesChecker {

	/*
	 * Get the expression wrapped by the parentheses
	 * i.e. ((((expression)))) -> expression
	 */
	private static Expression getExpression(ParenthesizedExpression node) {
		Expression expression= node.getExpression();
		while (expression instanceof ParenthesizedExpression) {
			expression= ((ParenthesizedExpression)expression).getExpression();
		}
		return expression;
	}

	private static boolean expressionTypeNeedsParentheses(Expression expression) {
		int type= expression.getNodeType();
		return type == ASTNode.INFIX_EXPRESSION
				|| type == ASTNode.CONDITIONAL_EXPRESSION
				|| type == ASTNode.PREFIX_EXPRESSION
				|| type == ASTNode.POSTFIX_EXPRESSION
				|| type == ASTNode.CAST_EXPRESSION
				|| type == ASTNode.INSTANCEOF_EXPRESSION
				|| type == ASTNode.ARRAY_CREATION
				|| type == ASTNode.ASSIGNMENT;
	}

	private static boolean locationNeedsParentheses(StructuralPropertyDescriptor locationInParent) {
		if (locationInParent instanceof ChildListPropertyDescriptor && locationInParent != InfixExpression.EXTENDED_OPERANDS_PROPERTY) {
			// e.g. argument lists of MethodInvocation, ClassInstanceCreation, dimensions of ArrayCreation ...
			return false;
		}
		if (locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY
				|| locationInParent == SingleVariableDeclaration.INITIALIZER_PROPERTY
				|| locationInParent == ReturnStatement.EXPRESSION_PROPERTY
				|| locationInParent == EnhancedForStatement.EXPRESSION_PROPERTY
				|| locationInParent == ForStatement.EXPRESSION_PROPERTY
				|| locationInParent == WhileStatement.EXPRESSION_PROPERTY
				|| locationInParent == DoStatement.EXPRESSION_PROPERTY
				|| locationInParent == AssertStatement.EXPRESSION_PROPERTY
				|| locationInParent == AssertStatement.MESSAGE_PROPERTY
				|| locationInParent == IfStatement.EXPRESSION_PROPERTY
				|| locationInParent == SwitchStatement.EXPRESSION_PROPERTY
				|| locationInParent == SwitchCase.EXPRESSION_PROPERTY
				|| locationInParent == ArrayAccess.INDEX_PROPERTY
				|| locationInParent == ThrowStatement.EXPRESSION_PROPERTY
				|| locationInParent == SynchronizedStatement.EXPRESSION_PROPERTY
				|| locationInParent == ParenthesizedExpression.EXPRESSION_PROPERTY) {
			return false;
		}
		return true;
	}

	/*
	 * Do all operands in expression have same type
	 */
	private static boolean isAllOperandsHaveSameType(InfixExpression expression, ITypeBinding leftOperandType, ITypeBinding rightOperandType) {
		ITypeBinding binding= leftOperandType;
		if (binding == null)
			return false;
	
		ITypeBinding current= rightOperandType;
		if (binding != current)
			return false;
	
		for (Iterator<Expression> iterator= expression.extendedOperands().iterator(); iterator.hasNext();) {
			Expression operand= iterator.next();
			current= operand.resolveTypeBinding();
			if (binding != current)
				return false;
		}
	
		return true;
	}

	private static boolean isIntegerType(ITypeBinding binding) {
		if (binding == null)
			return false;

		if (!binding.isPrimitive())
			return false;

		String name= binding.getName();
		if (isIntegerNumber(name))
			return true;

		return false;
	}

	private static boolean isStringType(ITypeBinding binding) {
		if (binding == null)
			return false;

		return "java.lang.String".equals(binding.getQualifiedName()); //$NON-NLS-1$
	}

	/*
	 * Is the given expression associative?
	 * 
	 * This is true if and only if:<br>
	 * <code>left operator (right) == (right) operator left == right operator left</code>
	 */
	private static boolean isAssociative(InfixExpression.Operator operator, ITypeBinding infixExprType, boolean isAllOperandsHaveSameType) {
		if (operator == InfixExpression.Operator.PLUS)
			return isStringType(infixExprType) || isIntegerType(infixExprType) && isAllOperandsHaveSameType;

		if (operator == InfixExpression.Operator.TIMES)
			return isIntegerType(infixExprType) && isAllOperandsHaveSameType;

		if (operator == InfixExpression.Operator.CONDITIONAL_AND
				|| operator == InfixExpression.Operator.CONDITIONAL_OR
				|| operator == InfixExpression.Operator.AND
				|| operator == InfixExpression.Operator.OR
				|| operator == InfixExpression.Operator.XOR)
			return true;
	
		return false;
	}

	private static boolean isIntegerNumber(String name) {
		return "int".equals(name) || "long".equals(name) || "byte".equals(name) || "char".equals(name) || "short".equals(name); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
	}

	private static boolean needsParenthesesInInfixExpression(Expression expression, InfixExpression parentInfix, StructuralPropertyDescriptor locationInParent,
			ITypeBinding leftOperandType) {
		InfixExpression.Operator parentInfixOperator= parentInfix.getOperator();
		ITypeBinding rightOperandType;
		ITypeBinding parentInfixExprType;
		if (leftOperandType == null) { // parentInfix has bindings
			leftOperandType= parentInfix.getLeftOperand().resolveTypeBinding();
			rightOperandType= parentInfix.getRightOperand().resolveTypeBinding();
			parentInfixExprType= parentInfix.resolveTypeBinding();
		} else {
			rightOperandType= expression.resolveTypeBinding();
			parentInfixExprType= getInfixExpressionType(parentInfixOperator, leftOperandType, rightOperandType);
		}
		boolean isAllOperandsHaveSameType= isAllOperandsHaveSameType(parentInfix, leftOperandType, rightOperandType);

		if (locationInParent == InfixExpression.LEFT_OPERAND_PROPERTY) {
			//we have (expr op expr) op expr
			//infix expressions are evaluated from left to right -> parentheses not needed
			return false;
		} else if (isAssociative(parentInfixOperator, parentInfixExprType, isAllOperandsHaveSameType)) {
			//we have parent op (expr op expr) and op is associative
			//left op (right) == (right) op left == right op left
			if (expression instanceof InfixExpression) {
				InfixExpression infixExpression= (InfixExpression)expression;
				Operator operator= infixExpression.getOperator();

				if (isStringType(parentInfixExprType)) {
					if (parentInfixOperator == InfixExpression.Operator.PLUS && operator == InfixExpression.Operator.PLUS && isStringType(infixExpression.resolveTypeBinding())) {
						// 1 + ("" + 2) == 1 + "" + 2
						// 1 + (2 + "") != 1 + 2 + ""
						// "" + (2 + "") == "" + 2 + ""
						return !isStringType(infixExpression.getLeftOperand().resolveTypeBinding()) && !isStringType(leftOperandType);
					}
					//"" + (1 + 2), "" + (1 - 2) etc
					return true;
				}

				if (parentInfixOperator != InfixExpression.Operator.TIMES)
					return false;
	
				if (operator == InfixExpression.Operator.TIMES)
					// x * (y * z) == x * y * z
					return false;
	
				if (operator == InfixExpression.Operator.REMAINDER || operator == InfixExpression.Operator.DIVIDE)
					// x * (y % z) != x * y % z , x * (y / z) == x * y / z rounding involved
					return true;
	
				return false;
			}
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Returns the type of infix expression based on its operands and operator.
	 * 
	 * @param operator the operator of infix expression
	 * @param leftOperandType the type of left operand of infix expression
	 * @param rightOperandType the type of right operand of infix expression
	 * @return the type of infix expression if the type of both the operands is same or if the type
	 *         of either operand of a + operator is String, <code>null</code> otherwise.
	 * 
	 * @since 3.9
	 */
	private static ITypeBinding getInfixExpressionType(InfixExpression.Operator operator, ITypeBinding leftOperandType, ITypeBinding rightOperandType) {
		if (leftOperandType == rightOperandType) {
			return leftOperandType;
		}
		if (operator == InfixExpression.Operator.PLUS) {
			if (isStringType(leftOperandType)) {
				return leftOperandType;
			} else if (isStringType(rightOperandType)) {
				return rightOperandType;
			}
		}
		// If the left and right operand types are different, we assume that parentheses are needed.
		// This is to avoid complications of numeric promotions and for readability of complicated code.
		return null;
	}

	/**
	 * Can the parentheses be removed from the parenthesized expression ?
	 * 
	 * <p>
	 * <b>Note:</b> The parenthesized expression must not be an unparented node.
	 * </p>
	 * 
	 * @param expression the parenthesized expression
	 * @return <code>true</code> if parentheses can be removed, <code>false</code> otherwise.
	 */
	public static boolean canRemoveParentheses(Expression expression) {
		return canRemoveParentheses(expression, expression.getParent(), expression.getLocationInParent());
	}

	/**
	 * Can the parentheses be removed from the parenthesized expression when inserted into
	 * <code>parent</code> at <code>locationInParent</code> ?
	 * 
	 * <p>
	 * <b>Note:</b> The parenthesized expression can be an unparented node.
	 * </p>
	 * 
	 * @param expression the parenthesized expression
	 * @param parent the parent node
	 * @param locationInParent location of expression in the parent
	 * @return <code>true</code> if parentheses can be removed, <code>false</code> otherwise.
	 */
	public static boolean canRemoveParentheses(Expression expression, ASTNode parent, StructuralPropertyDescriptor locationInParent) {
		if (!(expression instanceof ParenthesizedExpression)) {
			return false;
		}
		return !needsParentheses(getExpression((ParenthesizedExpression)expression), parent, locationInParent);
	}

	/**
	 * Does the <code>rightOperand</code> need parentheses when inserted into
	 * <code>infixExpression</code> ?
	 * 
	 * <p>
	 * <b>Note:</b>
	 * <ul>
	 * <li>The <code>infixExpression</code> can be a new node (not from a resolved AST) with no
	 * bindings.</li>
	 * <li>The <code>infixExpression</code> must not have additional operands.</li>
	 * <li>The <code>rightOperand</code> node must have bindings.</li>
	 * </ul>
	 * </p>
	 * 
	 * @param rightOperand the right operand in <code>infixExpression</code>
	 * @param infixExpression the parent infix expression
	 * @param leftOperandType the type of the left operand in <code>infixExpression</code>
	 * @return <code>true</code> if <code>rightOperand</code> needs parentheses, <code>false</code>
	 *         otherwise.
	 * 
	 * @since 3.9
	 */
	public static boolean needsParenthesesForRightOperand(Expression rightOperand, InfixExpression infixExpression, ITypeBinding leftOperandType) {
		return needsParentheses(rightOperand, infixExpression, InfixExpression.RIGHT_OPERAND_PROPERTY, leftOperandType);
	}

	/**
	 * Does the <code>expression</code> need parentheses when inserted into <code>parent</code> at
	 * <code>locationInParent</code> ?
	 * 
	 * <p>
	 * <b>Note:</b> The expression can be an unparented node.
	 * </p>
	 * 
	 * @param expression the expression
	 * @param parent the parent node
	 * @param locationInParent location of expression in the parent
	 * @return <code>true</code> if <code>expression</code> needs parentheses, <code>false</code>
	 *         otherwise.
	 */
	public static boolean needsParentheses(Expression expression, ASTNode parent, StructuralPropertyDescriptor locationInParent) {
		return needsParentheses(expression, parent, locationInParent, null);
	}

	/**
	 * Does the <code>expression</code> need parentheses when inserted into <code>parent</code> at
	 * <code>locationInParent</code> ?
	 * 
	 * @param expression the expression
	 * @param parent the parent node
	 * @param locationInParent location of expression in the parent
	 * @param leftOperandType the type of the left operand in <code>parent</code> if
	 *            <code>parent</code> is an infix expression with no bindings and
	 *            <code>expression</code> is the right operand in it, <code>null</code> otherwise
	 * @return <code>true</code> if <code>expression</code> needs parentheses, <code>false</code>
	 *         otherwise.
	 * 
	 * @since 3.9
	 */
	private static boolean needsParentheses(Expression expression, ASTNode parent, StructuralPropertyDescriptor locationInParent, ITypeBinding leftOperandType) {
		if (!expressionTypeNeedsParentheses(expression))
			return false;

		if (!locationNeedsParentheses(locationInParent)) {
			return false;
		}

		if (parent instanceof Expression) {
			Expression parentExpression= (Expression)parent;
			
			if (expression instanceof PrefixExpression) { // see bug 405096
				return needsParenthesesForPrefixExpression(parentExpression, ((PrefixExpression) expression).getOperator());
			}

			if (expression instanceof ArrayCreation) { // see bug 394721
				return parentExpression instanceof ArrayAccess && ((ArrayCreation) expression).getInitializer() == null;
			}

			int expressionPrecedence= OperatorPrecedence.getExpressionPrecedence(expression);
			int parentPrecedence= OperatorPrecedence.getExpressionPrecedence(parentExpression);

			if (expressionPrecedence > parentPrecedence)
				//(opEx) opParent and opEx binds more -> parentheses not needed
				return false;

			if (expressionPrecedence < parentPrecedence)
				//(opEx) opParent and opEx binds less -> parentheses needed
				return true;

			//(opEx) opParent binds equal

			if (parentExpression instanceof InfixExpression) {
				return needsParenthesesInInfixExpression(expression, (InfixExpression) parentExpression, locationInParent, leftOperandType);
			}

			if (parentExpression instanceof ConditionalExpression && locationInParent == ConditionalExpression.EXPRESSION_PROPERTY) {
				return true;
			}

			return false;
		}

		return true;
	}
	
	private static boolean needsParenthesesForPrefixExpression(Expression parentExpression, PrefixExpression.Operator expressionOperator) {
		if (parentExpression instanceof PrefixExpression) {
			PrefixExpression.Operator parentOperator= ((PrefixExpression) parentExpression).getOperator();
			if (parentOperator == PrefixExpression.Operator.PLUS &&
					(expressionOperator == PrefixExpression.Operator.PLUS || expressionOperator == PrefixExpression.Operator.INCREMENT)) {
				return true;
			}
			if (parentOperator == PrefixExpression.Operator.MINUS &&
					(expressionOperator == PrefixExpression.Operator.MINUS || expressionOperator == PrefixExpression.Operator.DECREMENT)) {
				return true;
			}
		} else if (parentExpression instanceof InfixExpression) {
			InfixExpression.Operator parentOperator= ((InfixExpression) parentExpression).getOperator();
			if (parentOperator == InfixExpression.Operator.PLUS &&
					(expressionOperator == PrefixExpression.Operator.PLUS || expressionOperator == PrefixExpression.Operator.INCREMENT)) {
				return true;
			}
			if (parentOperator == InfixExpression.Operator.MINUS &&
					(expressionOperator == PrefixExpression.Operator.MINUS || expressionOperator == PrefixExpression.Operator.DECREMENT)) {
				return true;
			}
		}
		return false;
	}
}