/*******************************************************************************
 * Copyright (c) 2011, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.core.manipulation.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;

/**
 * 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 == SwitchCase.EXPRESSIONS2_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;
	}
}