/*******************************************************************************
 * Copyright (c) 2017, 2018 Till Brychcy 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:
 *     Till Brychcy - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.corext.codemanipulation;

import java.lang.annotation.ElementType;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IAnnotationBinding;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.IMemberValuePairBinding;
import org.eclipse.jdt.core.dom.IModuleBinding;
import org.eclipse.jdt.core.dom.IPackageBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationExpression;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite.TypeLocation;

/* @NonNullByDefault */
public class RedundantNullnessTypeAnnotationsFilter {

	private static final IAnnotationBinding[] NO_ANNOTATIONS= new IAnnotationBinding[0];

	/**
	 * Locations where both {@code @NonNull} and {@code @Nullable} should always be filtered:
	 * <ul>
	 * <li>for local variables, nullity is inferred by flow analysis.
	 * <li>casts with null annotation would always be unchecked.
	 * <li>for exceptions, and {@code new} expressions non-null is implied.
	 * <li>in other mentioned locations null annotations are not supported for other reasons.
	 * </ul>
	 */
	private static final EnumSet<TypeLocation> NEVER_NULLNESS_LOCATIONS= EnumSet.of(
			TypeLocation.LOCAL_VARIABLE, TypeLocation.CAST,
			TypeLocation.EXCEPTION, TypeLocation.NEW,
			TypeLocation.INSTANCEOF, TypeLocation.RECEIVER);

	public static /* @Nullable */ RedundantNullnessTypeAnnotationsFilter createIfConfigured(/* @Nullable */ ASTNode node) {
		if (node == null) {
			return null;
		}
		final ASTNode root= node.getRoot();
		if (root instanceof CompilationUnit) {
			CompilationUnit compilationUnit= (CompilationUnit) root;
			IJavaElement javaElement= compilationUnit.getJavaElement();
			IJavaProject javaProject= javaElement == null ? null : javaElement.getJavaProject();
			if (javaProject != null) {
				if (JavaCore.ENABLED.equals(javaProject.getOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, true))) {
					String nonNullAnnotationName= javaProject.getOption(JavaCore.COMPILER_NONNULL_ANNOTATION_NAME, true);
					String nullableAnnotationName= javaProject.getOption(JavaCore.COMPILER_NULLABLE_ANNOTATION_NAME, true);
					Set<String> nonNullByDefaultNames= determineNonNullByDefaultNames(javaProject);
					if (nonNullAnnotationName == null || nullableAnnotationName == null || nonNullByDefaultNames == null) {
						return null;
					}
					EnumSet<TypeLocation> nonNullByDefaultLocations= determineNonNullByDefaultLocations(node, nonNullByDefaultNames);
					return new RedundantNullnessTypeAnnotationsFilter(nonNullAnnotationName, nullableAnnotationName, nonNullByDefaultLocations);
				}
			}
		}
		return null;
	}

	public static /* Nullable */ Set<String> determineNonNullByDefaultNames(IJavaProject javaProject) {
		String nonNullByDefaultName= javaProject.getOption(JavaCore.COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_NAME, true);
		if (nonNullByDefaultName == null) {
			return null;
		}
		LinkedHashSet<String> nonNullByDefaultNames= new LinkedHashSet<>();
		nonNullByDefaultNames.add(nonNullByDefaultName);
		String secondaryNNBDNames= javaProject.getOption(JavaCore.COMPILER_NONNULL_BY_DEFAULT_ANNOTATION_SECONDARY_NAMES, true);
		if (secondaryNNBDNames != null) {
			for (String string : secondaryNNBDNames.split(",")) { //$NON-NLS-1$
				string= string.trim();
				if (string.length() > 0) {
					nonNullByDefaultNames.add(string);
				}
			}
		}
		return nonNullByDefaultNames;
	}

	public static EnumSet<TypeLocation> determineNonNullByDefaultLocations(ASTNode astNode, Set<String> nonNullByDefaultNames) {
		// look for first @NonNullByDefault
		while (astNode != null) {
			List<IAnnotationBinding> annots= getNNBDAnnotations(astNode, nonNullByDefaultNames);
			if (annots != null) {
				return determineNNBDValue(annots);
			}
			astNode= astNode.getParent();
		}
		return EnumSet.noneOf(TypeLocation.class);
	}

	private static EnumSet<TypeLocation> determineNNBDValue(List<IAnnotationBinding> annots) {
		EnumSet<TypeLocation> result= EnumSet.noneOf(TypeLocation.class);
		for (IAnnotationBinding annot : annots) {
			IMemberValuePairBinding[] pairs= annot.getAllMemberValuePairs();
			if (pairs.length == 0) {
				ITypeBinding annotationType= annot.getAnnotationType();
				boolean foundTypeQualifierDefault= false;
				if (annotationType != null) {
					IAnnotationBinding[] annotationAnnotations= annotationType.getAnnotations();
					for (IAnnotationBinding nestedBinding : annotationAnnotations) {
						ITypeBinding nestedAnnotationType= nestedBinding.getAnnotationType();
						if (nestedAnnotationType != null) {
							if (nestedAnnotationType.getName().equals("TypeQualifierDefault")) { //$NON-NLS-1$
								foundTypeQualifierDefault= true;
								for (final IMemberValuePairBinding pair : nestedBinding.getAllMemberValuePairs()) {
									if (pair.getKey() == null || pair.getKey().equals("value")) { //$NON-NLS-1$
										Object value= pair.getValue();
										if (value instanceof Object[]) {
											Object[] values= (Object[]) value;
											for (Object elem : values) {
												addElementTypesAsTypeLocationValues(result, elem);
											}
										} else {
											addElementTypesAsTypeLocationValues(result, value);
										}
									}
								}
								break;
							}
						}
					}
				}
				if (!foundTypeQualifierDefault) {
					// unconfigurable NonNullByDefault annotation
					addAsTypeLocationValues(result, Boolean.TRUE);
				}
			} else {
				for (final IMemberValuePairBinding pair : pairs) {
					if (pair.getKey() == null || pair.getKey().equals("value")) { //$NON-NLS-1$
						Object value= pair.getValue();
						if (value instanceof Object[]) {
							Object[] values= (Object[]) value;
							for (Object elem : values) {
								addAsTypeLocationValues(result, elem);
							}
						} else {
							addAsTypeLocationValues(result, value);
						}
					}
				}
			}
		}
		return result;
	}

	private static void addAsTypeLocationValues(EnumSet<TypeLocation> result, Object value) {
		if (value instanceof IVariableBinding) {
			String name= ((IVariableBinding) value).getName();
			try {
				result.add(TypeLocation.valueOf(name));
			} catch (IllegalArgumentException e) {
				// ignore
			}
		} else if (value instanceof Boolean) {
			if (((Boolean) value).booleanValue()) {
				result.add(TypeLocation.RETURN_TYPE);
				result.add(TypeLocation.PARAMETER);
				result.add(TypeLocation.FIELD);
			}
		}
	}

	private static void addElementTypesAsTypeLocationValues(EnumSet<TypeLocation> result, Object value) {
		if (value instanceof IVariableBinding) {
			String name= ((IVariableBinding) value).getName();
			if (ElementType.PARAMETER.name().equals(name)) {
				result.add(TypeLocation.PARAMETER);
			} else if (ElementType.METHOD.name().equals(name)) {
				result.add(TypeLocation.RETURN_TYPE);
			} else if (ElementType.FIELD.name().equals(name)) {
				result.add(TypeLocation.FIELD);
			}
		}
	}

	// based on org.eclipse.jdt.apt.core.internal.declaration.ASTBasedDeclarationImpl.getAnnotationInstancesFromAST()
	private static /* @Nullable */ List<IAnnotationBinding> getNNBDAnnotations(ASTNode astNode, Set<String> nonNullByDefaultNames) {
		List<IExtendedModifier> extendsMods= null;
		ArrayList<IAnnotationBinding> list= null;
		switch (astNode.getNodeType()) {
			case ASTNode.COMPILATION_UNIT: {
				// special case: when reaching the root of the ast, check the package and module annotations.
				PackageDeclaration packageDeclaration= ((CompilationUnit) astNode).getPackage();
				if (packageDeclaration != null) {
					IPackageBinding packageBinding= packageDeclaration.resolveBinding();
					if (packageBinding != null) {
						for (IAnnotationBinding annotationBinding : packageBinding.getAnnotations()) {
							ITypeBinding annotationType= annotationBinding.getAnnotationType();
							if (annotationType != null) {
								if (nonNullByDefaultNames.contains(annotationType.getQualifiedName())) {
									if (list == null)
										list= new ArrayList<>();
									list.add(annotationBinding);
								}
							}
						}
						if (list != null)
							return list;
						IModuleBinding module= packageBinding.getModule();
						if (module != null) {
							for (IAnnotationBinding annotationBinding : module.getAnnotations()) {
								ITypeBinding annotationType= annotationBinding.getAnnotationType();
								if (annotationType != null && nonNullByDefaultNames.contains(annotationType.getQualifiedName())) {
									if (list == null)
										list= new ArrayList<>();
									list.add(annotationBinding);
								}
							}
							if (list != null)
								return list;
						}
					}
				}
				return null;
			}
			case ASTNode.TYPE_DECLARATION:
			case ASTNode.ANNOTATION_TYPE_DECLARATION:
			case ASTNode.ENUM_DECLARATION:
			case ASTNode.ANNOTATION_TYPE_MEMBER_DECLARATION:
			case ASTNode.METHOD_DECLARATION:
			case ASTNode.FIELD_DECLARATION:
			case ASTNode.ENUM_CONSTANT_DECLARATION:
				extendsMods= ((BodyDeclaration) astNode).modifiers();
				break;

			case ASTNode.VARIABLE_DECLARATION_STATEMENT:
				extendsMods= ((VariableDeclarationStatement) astNode).modifiers();
				break;

			case ASTNode.VARIABLE_DECLARATION_EXPRESSION:
				extendsMods= ((VariableDeclarationExpression) astNode).modifiers();
				break;

			case ASTNode.SINGLE_VARIABLE_DECLARATION:
				extendsMods= ((SingleVariableDeclaration) astNode).modifiers();
				break;
			case ASTNode.VARIABLE_DECLARATION_FRAGMENT:
				final ASTNode parent= ((VariableDeclarationFragment) astNode).getParent();
				if (parent instanceof BodyDeclaration)
					extendsMods= ((BodyDeclaration) parent).modifiers();
				break;

			default:
				return null;
		}
		if (extendsMods != null) {
			for (IExtendedModifier extMod : extendsMods) {
				if (extMod.isAnnotation()) {
					Annotation annotation= (Annotation) extMod;
					IAnnotationBinding annotationBinding= annotation.resolveAnnotationBinding();
					if (annotationBinding != null) {
						ITypeBinding annotationType= annotationBinding.getAnnotationType();
						if (annotationType != null && nonNullByDefaultNames.contains(annotationType.getQualifiedName())) {
							if (list == null)
								list= new ArrayList<>();
							list.add(annotationBinding);
						}
					}
				}
			}
			if (list != null)
				return list;
		}
		return null;
	}

	private final String fNonNullAnnotationName;

	private final String fNullableAnnotationName;

	private final EnumSet<TypeLocation> fNonNullByDefaultLocations;

	public RedundantNullnessTypeAnnotationsFilter(String nonNullAnnotationName, String nullableAnnotationName, EnumSet<TypeLocation> nonNullByDefaultLocations) {
		fNonNullAnnotationName= nonNullAnnotationName;
		fNullableAnnotationName= nullableAnnotationName;
		fNonNullByDefaultLocations= nonNullByDefaultLocations;
	}

	public IAnnotationBinding[] removeUnwantedTypeAnnotations(IAnnotationBinding[] annotations, TypeLocation location, ITypeBinding type) {
		if (location == TypeLocation.OTHER)
			return NO_ANNOTATIONS;
		if (type.isTypeVariable() || type.isWildcardType()) {
			return annotations;
		}
		boolean excludeAllNullAnnotations= NEVER_NULLNESS_LOCATIONS.contains(location);
		if (excludeAllNullAnnotations || fNonNullByDefaultLocations.contains(location)) {
			ArrayList<IAnnotationBinding> list= new ArrayList<>(annotations.length);
			for (IAnnotationBinding annotation : annotations) {
				ITypeBinding annotationType= annotation.getAnnotationType();
				if (annotationType != null) {
					if (annotationType.getQualifiedName().equals(fNonNullAnnotationName)) {
						// ignore @NonNull
					} else if (excludeAllNullAnnotations && annotationType.getQualifiedName().equals(fNullableAnnotationName)) {
						// also ignore @Nullable
					} else {
						list.add(annotation);
					}
				} else {
					list.add(annotation);
				}
			}
			return list.size() == annotations.length ? annotations : list.toArray(new IAnnotationBinding[list.size()]);
		} else {
			return annotations;
		}
	}
}
