/*******************************************************************************
 * Copyright (c) 2000, 2018 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.refactoring.structure;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IBinding;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IVariableBinding;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NameQualifiedType;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.QualifiedType;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.manipulation.ImportReferencesCollector;

import org.eclipse.jdt.internal.corext.dom.Bindings;

/**
 * Removes imports that are no longer required.
 * <p>
 * {@link #registerRemovedNode(ASTNode)} registers nodes that got removed from the AST.
 * Do not register nodes that are moved to a different place in the same AST.
 * <p>
 * If a node is removed but some parts of it are moved to a different place in the same AST,
 * then use {@link #registerRetainedNode(ASTNode)} to keep imports for the retained nodes.
 * <p>
 * Additional imports that will be added to the AST need to be registered with one of the
 * {@code register*Import*(..)} methods. Such imports have typically been created with
 * {@link ImportRewrite#addImport(ITypeBinding)} etc.
 */
public class ImportRemover {

	private static class StaticImportData {

		private boolean fField;

		private String fMember;

		private String fQualifier;

		private StaticImportData(String qualifier, String member, boolean field) {
			fQualifier= qualifier;
			fMember= member;
			fField= field;
		}
	}

	private final String PROPERTY_KEY= String.valueOf(System.currentTimeMillis());
	private final String REMOVED= "removed"; //$NON-NLS-1$
	private final String RETAINED= "retained"; //$NON-NLS-1$
	
	private Set<String> fAddedImports= new HashSet<>();

	private Set<StaticImportData> fAddedStaticImports= new HashSet<>();

	private final IJavaProject fProject;

	private boolean fHasRemovedNodes;

	private List<ImportDeclaration> fInlinedStaticImports= new ArrayList<>();

	private final CompilationUnit fRoot;

	public ImportRemover(IJavaProject project, CompilationUnit root) {
		fProject= project;
		fRoot= root;
	}

	private void divideTypeRefs(List<SimpleName> importNames, List<SimpleName> staticNames, List<SimpleName> removedRefs, List<SimpleName> unremovedRefs) {
		final List<int[]> removedStartsEnds= new ArrayList<>();
		fRoot.accept(new ASTVisitor(true) {
			int fRemovingStart= -1;
			@Override
			public void preVisit(ASTNode node) {
				Object property= node.getProperty(PROPERTY_KEY);
				if (property == REMOVED) {
					if (fRemovingStart == -1) {
						fRemovingStart= node.getStartPosition();
					} else {
						/*
						 * Bug in client code: REMOVED node should not be nested inside another REMOVED node without
						 * an intermediate RETAINED node.
						 * Drop REMOVED property to prevent problems later (premature end of REMOVED section).
						 */
						node.setProperty(PROPERTY_KEY, null);
					}
				} else if (property == RETAINED) {
					if (fRemovingStart != -1) {
						removedStartsEnds.add(new int[] { fRemovingStart, node.getStartPosition() });
						fRemovingStart= -1;
					} else {
						/*
						 * Bug in client code: RETAINED node should not be nested inside another RETAINED node without
						 * an intermediate REMOVED node and must have an enclosing REMOVED node.
						 * Drop RETAINED property to prevent problems later (premature restart of REMOVED section).
						 */
						node.setProperty(PROPERTY_KEY, null);
					}
				}
				super.preVisit(node);
			}
			@Override
			public void postVisit(ASTNode node) {
				Object property= node.getProperty(PROPERTY_KEY);
				if (property == RETAINED) {
					int end= node.getStartPosition() + node.getLength();
					fRemovingStart= end;
				} else if (property == REMOVED) {
					if (fRemovingStart != -1) {
						int end= node.getStartPosition() + node.getLength();
						removedStartsEnds.add(new int[] { fRemovingStart, end });
						fRemovingStart= -1;
					}
				}
				super.postVisit(node);
			}
		});
		
		for (Iterator<SimpleName> iterator= importNames.iterator(); iterator.hasNext();) {
			SimpleName name= iterator.next();
			if (isInRemoved(name, removedStartsEnds))
				removedRefs.add(name);
			else
				unremovedRefs.add(name);
		}
		for (Iterator<SimpleName> iterator= staticNames.iterator(); iterator.hasNext();) {
			SimpleName name= iterator.next();
			if (isInRemoved(name, removedStartsEnds))
				removedRefs.add(name);
			else
				unremovedRefs.add(name);
		}
		for (Iterator<ImportDeclaration> iterator= fInlinedStaticImports.iterator(); iterator.hasNext(); ) {
			ImportDeclaration importDecl= iterator.next();
			Name name= importDecl.getName();
			if (name instanceof QualifiedName)
				name= ((QualifiedName) name).getName();
			removedRefs.add((SimpleName) name);
		}
	}

	private boolean isInRemoved(SimpleName ref, List<int[]> removedStartsEnds) {
		int start= ref.getStartPosition();
		int end= start + ref.getLength();
		for (int[] removedStartsEnd : removedStartsEnds) {
			if (start >= removedStartsEnd[0] && end <= removedStartsEnd[1]) {
				return true;
			}
		}
		return false;
	}

	public IBinding[] getImportsToRemove() {
		ArrayList<SimpleName> importNames= new ArrayList<>();
		ArrayList<SimpleName> staticNames= new ArrayList<>();

		ImportReferencesCollector.collect(fRoot, fProject, null, importNames, staticNames);

		List<SimpleName> removedRefs= new ArrayList<>();
		List<SimpleName> unremovedRefs= new ArrayList<>();
		divideTypeRefs(importNames, staticNames, removedRefs, unremovedRefs);
		if (removedRefs.size() == 0)
			return new IBinding[0];

		HashMap<String, IBinding> potentialRemoves= getPotentialRemoves(removedRefs);
		for (Iterator<SimpleName> iterator= unremovedRefs.iterator(); iterator.hasNext();) {
			SimpleName name= iterator.next();
			potentialRemoves.remove(name.getIdentifier());
		}

		Collection<IBinding> importsToRemove= potentialRemoves.values();
		return importsToRemove.toArray(new IBinding[importsToRemove.size()]);
	}

	private HashMap<String, IBinding> getPotentialRemoves(List<SimpleName> removedRefs) {
		HashMap<String, IBinding>potentialRemoves= new HashMap<>();
		for (Iterator<SimpleName> iterator= removedRefs.iterator(); iterator.hasNext();) {
			SimpleName name= iterator.next();
			if (fAddedImports.contains(name.getIdentifier()) || hasAddedStaticImport(name))
				continue;
			IBinding binding= name.resolveBinding();
			if (binding != null)
				potentialRemoves.put(name.getIdentifier(), binding);
		}
		return potentialRemoves;
	}

	private boolean hasAddedStaticImport(SimpleName name) {
		IBinding binding= name.resolveBinding();
		if (binding instanceof IVariableBinding) {
			IVariableBinding variable= (IVariableBinding) binding;
			return hasAddedStaticImport(variable.getDeclaringClass().getQualifiedName(), variable.getName(), true);
		} else if (binding instanceof IMethodBinding) {
			IMethodBinding method= (IMethodBinding) binding;
			return hasAddedStaticImport(method.getDeclaringClass().getQualifiedName(), method.getName(), false);
		}
		return false;
	}

	private boolean hasAddedStaticImport(String qualifier, String member, boolean field) {
		StaticImportData data= null;
		for (final Iterator<StaticImportData> iterator= fAddedStaticImports.iterator(); iterator.hasNext();) {
			data= iterator.next();
			if (data.fQualifier.equals(qualifier) && data.fMember.equals(member) && data.fField == field)
				return true;
		}
		return false;
	}

	public boolean hasRemovedNodes() {
		return fHasRemovedNodes || fInlinedStaticImports.size() != 0;
	}

	public void registerAddedImport(String typeName) {
		int dot= typeName.lastIndexOf('.');
		if (dot == -1)
			fAddedImports.add(typeName);
		else
			fAddedImports.add(typeName.substring(dot + 1));
	}

	public void registerAddedImports(Type newTypeNode) {
		newTypeNode.accept(new ASTVisitor(true) {

			private void addName(SimpleName name) {
				fAddedImports.add(name.getIdentifier());
			}

			@Override
			public boolean visit(NameQualifiedType node) {
				addName(node.getName());
				return false;
			}
			
			@Override
			public boolean visit(QualifiedName node) {
				addName(node.getName());
				return false;
			}

			@Override
			public boolean visit(QualifiedType node) {
				addName(node.getName());
				return false;
			}

			@Override
			public boolean visit(SimpleName node) {
				addName(node);
				return false;
			}
		});
	}

	public void registerAddedStaticImport(String qualifier, String member, boolean field) {
		fAddedStaticImports.add(new StaticImportData(qualifier, member, field));
	}

	public void registerAddedStaticImport(IBinding binding) {
		if (binding instanceof IVariableBinding) {
			ITypeBinding declaringType= ((IVariableBinding) binding).getDeclaringClass();
			fAddedStaticImports.add(new StaticImportData(Bindings.getRawQualifiedName(declaringType), binding.getName(), true));

		} else if (binding instanceof IMethodBinding) {
			ITypeBinding declaringType= ((IMethodBinding) binding).getDeclaringClass();
			fAddedStaticImports.add(new StaticImportData(Bindings.getRawQualifiedName(declaringType), binding.getName(), false));

		} else {
			throw new IllegalArgumentException(binding.toString());
		}
	}

	public void registerRemovedNode(ASTNode removed) {
		fHasRemovedNodes= true;
		removed.setProperty(PROPERTY_KEY, REMOVED);
	}

	public void registerRetainedNode(ASTNode retained) {
		retained.setProperty(PROPERTY_KEY, RETAINED);
	}

	public void applyRemoves(ImportRewrite importRewrite) {
		IBinding[] bindings= getImportsToRemove();
		for (int i= 0; i < bindings.length; i++) {
			if (bindings[i] instanceof ITypeBinding) {
				ITypeBinding typeBinding= (ITypeBinding) bindings[i];
				importRewrite.removeImport(typeBinding.getTypeDeclaration().getQualifiedName());
			} else if (bindings[i] instanceof IMethodBinding) {
				IMethodBinding binding= (IMethodBinding) bindings[i];
				importRewrite.removeStaticImport(binding.getDeclaringClass().getQualifiedName() + '.' + binding.getName());
			} else if (bindings[i] instanceof IVariableBinding) {
				IVariableBinding binding= (IVariableBinding) bindings[i];
				importRewrite.removeStaticImport(binding.getDeclaringClass().getQualifiedName() + '.' + binding.getName());
			}
		}
	}

	public void registerInlinedStaticImport(ImportDeclaration importDecl) {
		fInlinedStaticImports.add(importDecl);
	}
}
