/*******************************************************************************
 * Copyright (c) 2000, 2017 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
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.dom;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotatableType;
import org.eclipse.jdt.core.dom.ArrayType;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.Dimension;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.InfixExpression.Operator;
import org.eclipse.jdt.core.dom.LambdaExpression;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NodeFinder;
import org.eclipse.jdt.core.dom.ParameterizedType;
import org.eclipse.jdt.core.dom.PrimitiveType;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.UnionType;
import org.eclipse.jdt.core.dom.VariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;

import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2;
import org.eclipse.jdt.internal.corext.util.JDTUIHelperClasses;

/**
 * JDT-UI-internal helper methods to create new {@link ASTNode}s.
 * Complements <code>AST#new*(..)</code> and <code>ImportRewrite#add*(..)</code>.
 * 
 * @see JDTUIHelperClasses
 */
public class ASTNodeFactory {

	private static final String STATEMENT_HEADER= "class __X__ { void __x__() { "; //$NON-NLS-1$
	private static final String STATEMENT_FOOTER= "}}"; //$NON-NLS-1$

	private static final String TYPE_HEADER= "class __X__ { abstract "; //$NON-NLS-1$
	private static final String TYPE_FOOTER= " __f__(); }}"; //$NON-NLS-1$

	private static final String TYPEPARAM_HEADER= "class __X__ { abstract <"; //$NON-NLS-1$
	private static final String TYPEPARAM_FOOTER= "> void __f__(); }}"; //$NON-NLS-1$

	private static class PositionClearer extends GenericVisitor {

		public PositionClearer() {
			super(true);
		}

		@Override
		protected boolean visitNode(ASTNode node) {
			node.setSourceRange(-1, 0);
			return true;
		}
	}

	private ASTNodeFactory() {
		// no instance;
	}

	public static ASTNode newStatement(AST ast, String content) {
		StringBuffer buffer= new StringBuffer(STATEMENT_HEADER);
		buffer.append(content);
		buffer.append(STATEMENT_FOOTER);
		ASTParser p= ASTParser.newParser(ast.apiLevel());
		p.setSource(buffer.toString().toCharArray());
		CompilationUnit root= (CompilationUnit) p.createAST(null);
		ASTNode result= ASTNode.copySubtree(ast, NodeFinder.perform(root, STATEMENT_HEADER.length(), content.length()));
		result.accept(new PositionClearer());
		return result;
	}

	public static Name newName(AST ast, String qualifiedName) {
		return ast.newName(qualifiedName);
	}

	public static TypeParameter newTypeParameter(AST ast, String content) {
		StringBuffer buffer= new StringBuffer(TYPEPARAM_HEADER);
		buffer.append(content);
		buffer.append(TYPEPARAM_FOOTER);
		ASTParser p= ASTParser.newParser(ast.apiLevel());
		p.setSource(buffer.toString().toCharArray());
		CompilationUnit root= (CompilationUnit) p.createAST(null);
		List<AbstractTypeDeclaration> list= root.types();
		TypeDeclaration typeDecl= (TypeDeclaration) list.get(0);
		MethodDeclaration methodDecl= typeDecl.getMethods()[0];
		TypeParameter tp= (TypeParameter) methodDecl.typeParameters().get(0);
		ASTNode result= ASTNode.copySubtree(ast, tp);
		result.accept(new PositionClearer());
		return (TypeParameter) result;
	}


	public static Type newType(AST ast, String content) {
		StringBuffer buffer= new StringBuffer(TYPE_HEADER);
		buffer.append(content);
		buffer.append(TYPE_FOOTER);
		ASTParser p= ASTParser.newParser(ast.apiLevel());
		p.setSource(buffer.toString().toCharArray());
		CompilationUnit root= (CompilationUnit) p.createAST(null);
		List<AbstractTypeDeclaration> list= root.types();
		TypeDeclaration typeDecl= (TypeDeclaration) list.get(0);
		MethodDeclaration methodDecl= typeDecl.getMethods()[0];
		ASTNode type= methodDecl.getReturnType2();
		ASTNode result= ASTNode.copySubtree(ast, type);
		result.accept(new PositionClearer());
		return (Type)result;
	}

	/**
	 * Returns an {@link ArrayType} that adds one dimension to the given type node.
	 * If the given node is already an ArrayType, then a new {@link Dimension}
	 * without annotations is inserted at the first position.
	 * 
	 * @param type the type to be wrapped
	 * @return the array type
	 * @since 3.10
	 */
	public static ArrayType newArrayType(Type type) {
		if (type instanceof ArrayType) {
			Dimension dimension= type.getAST().newDimension();
			ArrayType arrayType= (ArrayType) type;
			arrayType.dimensions().add(0, dimension); // first dimension is outermost
			return arrayType;
		} else {
			return type.getAST().newArrayType(type);
		}
	}

	/**
	 * Returns the new type node corresponding to the type of the given declaration
	 * including the extra dimensions.
	 * @param ast The AST to create the resulting type with.
	 * @param declaration The variable declaration to get the type from
	 * @return a new type node created with the given AST.
	 */
	public static Type newType(AST ast, VariableDeclaration declaration) {
		return newType(ast, declaration, null, null);
	}

	/**
	 * Returns the new type node corresponding to the type of the given declaration
	 * including the extra dimensions. If the type is a {@link UnionType}, use the LUB type.
	 * If the <code>importRewrite</code> is <code>null</code>, the type may be fully-qualified.
	 * 
	 * @param ast The AST to create the resulting type with.
	 * @param declaration The variable declaration to get the type from
	 * @param importRewrite the import rewrite to use, or <code>null</code>
	 * @param context the import rewrite context, or <code>null</code>
	 * @return a new type node created with the given AST.
	 * 
	 * @since 3.7.1
	 */
	public static Type newType(AST ast, VariableDeclaration declaration, ImportRewrite importRewrite, ImportRewriteContext context) {
		if (declaration instanceof VariableDeclarationFragment && declaration.getParent() instanceof LambdaExpression) {
			return newType((LambdaExpression) declaration.getParent(), (VariableDeclarationFragment) declaration, ast, importRewrite, context);
		}

		Type type= ASTNodes.getType(declaration);
		if (declaration instanceof SingleVariableDeclaration) {
			Type type2= ((SingleVariableDeclaration) declaration).getType();
			if (type2 instanceof UnionType) {
				ITypeBinding typeBinding= type2.resolveBinding();
				if (typeBinding != null) {
					if (importRewrite != null) {
						type= importRewrite.addImport(typeBinding, ast, context);
						return type;
					} else {
						String qualifiedName= typeBinding.getQualifiedName();
						if (qualifiedName.length() > 0) {
							type= ast.newSimpleType(ast.newName(qualifiedName));
							return type;
						}
					}
				}
				// XXX: fallback for intersection types or unresolved types: take first type of union
				type= (Type) ((UnionType) type2).types().get(0);
				return type;
			}
		}
		
		type= (Type) ASTNode.copySubtree(ast, type);
		
		List<Dimension> extraDimensions= declaration.extraDimensions();
		if (!extraDimensions.isEmpty()) {
			ArrayType arrayType;
			if (type instanceof ArrayType) {
				arrayType= (ArrayType) type;
			} else {
				arrayType= ast.newArrayType(type, 0);
				type= arrayType;
			}
			arrayType.dimensions().addAll(ASTNode.copySubtrees(ast, extraDimensions));
		}
		return type;
	}

	private static Type newType(LambdaExpression lambdaExpression, VariableDeclarationFragment declaration, AST ast, ImportRewrite importRewrite, ImportRewriteContext context) {
		IMethodBinding method= lambdaExpression.resolveMethodBinding();
		if (method != null) {
			ITypeBinding[] parameterTypes= method.getParameterTypes();
			int index= lambdaExpression.parameters().indexOf(declaration);
			ITypeBinding typeBinding= parameterTypes[index];
			if (importRewrite != null) {
				return importRewrite.addImport(typeBinding, ast, context);
			} else {
				String qualifiedName= typeBinding.getQualifiedName();
				if (qualifiedName.length() > 0) {
					return newType(ast, qualifiedName);
				}
			}
		}
		// fall-back
		return ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$
	}

	/**
	 * Returns the new type node representing the return type of <code>lambdaExpression</code>
	 * including the extra dimensions.
	 * 
	 * @param lambdaExpression the lambda expression
	 * @param ast the AST to create the return type with
	 * @param importRewrite the import rewrite to use, or <code>null</code>
	 * @param context the import rewrite context, or <code>null</code>
	 * @return a new type node created with the given AST representing the return type of
	 *         <code>lambdaExpression</code>
	 * 
	 * @since 3.10
	 */
	public static Type newReturnType(LambdaExpression lambdaExpression, AST ast, ImportRewrite importRewrite, ImportRewriteContext context) {
		IMethodBinding method= lambdaExpression.resolveMethodBinding();
		if (method != null) {
			ITypeBinding returnTypeBinding= method.getReturnType();
			if (importRewrite != null) {
				return importRewrite.addImport(returnTypeBinding, ast);
			} else {
				String qualifiedName= returnTypeBinding.getQualifiedName();
				if (qualifiedName.length() > 0) {
					return newType(ast, qualifiedName);
				}
			}
		}
		// fall-back
		return ast.newSimpleType(ast.newSimpleName("Object")); //$NON-NLS-1$
	}

	/**
	 * Returns an expression that is assignable to the given type. <code>null</code> is
	 * returned if the type is the 'void' type.
	 *
	 * @param ast The AST to create the expression for
	 * @param type The type of the returned expression
	 * @param extraDimensions Extra dimensions to the type
	 * @return the Null-literal for reference types, a boolean-literal for a boolean type, a number
	 * literal for primitive types or <code>null</code> if the type is void.
	 */
	public static Expression newDefaultExpression(AST ast, Type type, int extraDimensions) {
		if (extraDimensions == 0 && type.isPrimitiveType()) {
			PrimitiveType primitiveType= (PrimitiveType) type;
			if (primitiveType.getPrimitiveTypeCode() == PrimitiveType.BOOLEAN) {
				return ast.newBooleanLiteral(false);
			} else if (primitiveType.getPrimitiveTypeCode() == PrimitiveType.VOID) {
				return null;
			} else {
				return ast.newNumberLiteral("0"); //$NON-NLS-1$
			}
		}
		return ast.newNullLiteral();
	}

	/**
	 * Returns an expression that is assignable to the given type binding. <code>null</code> is
	 * returned if the type is the 'void' type.
	 *
	 * @param ast The AST to create the expression for
	 * @param type The type binding to which the returned expression is compatible to
	 * @return the Null-literal for reference types, a boolean-literal for a boolean type, a number
	 * literal for primitive types or <code>null</code> if the type is void.
	 */
	public static Expression newDefaultExpression(AST ast, ITypeBinding type) {
		if (type.isPrimitive()) {
			String name= type.getName();
			if ("boolean".equals(name)) { //$NON-NLS-1$
				return ast.newBooleanLiteral(false);
			} else if ("void".equals(name)) { //$NON-NLS-1$
				return null;
			} else {
				return ast.newNumberLiteral("0"); //$NON-NLS-1$
			}
		}
		return ast.newNullLiteral();
	}

	/**
	 * Returns a list of newly created Modifier nodes corresponding to the given modifier flags.
	 * @param ast The AST to create the nodes for.
	 * @param modifiers The modifier flags describing the modifier nodes to create.
	 * @return Returns a list of nodes of type {@link Modifier}.
	 */
	public static List<Modifier> newModifiers(AST ast, int modifiers) {
		return ast.newModifiers(modifiers);
	}

	/**
	 * Returns a list of newly created Modifier nodes corresponding to a given list of existing modifiers.
	 * @param ast The AST to create the nodes for.
	 * @param modifierNodes The modifier nodes describing the modifier nodes to create. Only
	 * nodes of type {@link Modifier} are looked at and cloned. To create a full copy of the list consider
	 * to use {@link ASTNode#copySubtrees(AST, List)}.
	 * @return Returns a list of nodes of type {@link Modifier}.
	 */
	public static List<Modifier> newModifiers(AST ast, List<? extends IExtendedModifier> modifierNodes) {
		List<Modifier> res= new ArrayList<>(modifierNodes.size());
		for (int i= 0; i < modifierNodes.size(); i++) {
			Object curr= modifierNodes.get(i);
			if (curr instanceof Modifier) {
				res.add(ast.newModifier(((Modifier) curr).getKeyword()));
			}
		}
		return res;
	}

	public static Expression newInfixExpression(AST ast, Operator operator, ArrayList<Expression> operands) {
		if (operands.size() == 1)
			return operands.get(0);

		InfixExpression result= ast.newInfixExpression();
		result.setOperator(operator);
		result.setLeftOperand(operands.get(0));
		result.setRightOperand(operands.get(1));
		result.extendedOperands().addAll(operands.subList(2, operands.size()));
		return result;
	}

	/**
	 * Create a Type suitable as the creationType in a ClassInstanceCreation expression.
	 * @param ast The AST to create the nodes for.
	 * @param typeBinding binding representing the given class type
	 * @param importRewrite the import rewrite to use
	 * @param importContext the import context used to determine which (null) annotations to consider
	 * @return a Type suitable as the creationType in a ClassInstanceCreation expression.
	 */
	public static Type newCreationType(AST ast, ITypeBinding typeBinding, ImportRewrite importRewrite, ImportRewriteContext importContext) {
		if (typeBinding.isParameterizedType()) {
			Type baseType= newCreationType(ast, typeBinding.getTypeDeclaration(), importRewrite, importContext);
			IAnnotationBinding[] typeAnnotations= importContext.removeRedundantTypeAnnotations(typeBinding.getTypeAnnotations(), TypeLocation.NEW, typeBinding);
			for (IAnnotationBinding typeAnnotation : typeAnnotations) {
				((AnnotatableType)baseType).annotations().add(importRewrite.addAnnotation(typeAnnotation, ast, importContext));
			}
			ParameterizedType parameterizedType= ast.newParameterizedType(baseType);
			for (ITypeBinding typeArgument : typeBinding.getTypeArguments()) {
				typeArgument= StubUtility2.replaceWildcardsAndCaptures(typeArgument);
				parameterizedType.typeArguments().add(importRewrite.addImport(typeArgument, ast, importContext, TypeLocation.TYPE_ARGUMENT));
			}
			return parameterizedType;
		} else {
			return importRewrite.addImport(typeBinding, ast, importContext, TypeLocation.NEW);
		}
	}
}
