/*******************************************************************************
 * Copyright (c) 2000, 2016 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.reorg;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.SubProgressMonitor;

import org.eclipse.core.resources.IResource;

import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.TextChange;

import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IBuffer;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IImportDeclaration;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.compiler.ITerminalSymbols;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.core.dom.rewrite.ImportRewrite;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.TypeReferenceMatch;

import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility;
import org.eclipse.jdt.internal.corext.refactoring.CollectingSearchRequestor;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringScopeFactory;
import org.eclipse.jdt.internal.corext.refactoring.RefactoringSearchEngine;
import org.eclipse.jdt.internal.corext.refactoring.SearchResultGroup;
import org.eclipse.jdt.internal.corext.refactoring.base.ReferencesInBinaryContext;
import org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility;
import org.eclipse.jdt.internal.corext.refactoring.structure.ReferenceFinderUtil;
import org.eclipse.jdt.internal.corext.refactoring.util.TextChangeManager;
import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.jdt.internal.corext.util.SearchUtils;

import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.core.manipulation.util.BasicElementLabels;

public class MoveCuUpdateCreator {

	private final String fNewPackage;
	private ICompilationUnit[] fCus;
	private IPackageFragment fDestination;

	private Map<ICompilationUnit, ImportRewrite> fImportRewrites; //ICompilationUnit -> ImportEdit

	public MoveCuUpdateCreator(ICompilationUnit cu, IPackageFragment pack){
		this(new ICompilationUnit[]{cu}, pack);
	}

	public MoveCuUpdateCreator(ICompilationUnit[] cus, IPackageFragment pack){
		Assert.isNotNull(cus);
		Assert.isNotNull(pack);
		fCus= cus;
		fDestination= pack;
		fImportRewrites= new HashMap<>();
		fNewPackage= fDestination.isDefaultPackage() ? "" : fDestination.getElementName() + '.'; //$NON-NLS-1$
	}

	public TextChangeManager createChangeManager(IProgressMonitor pm, RefactoringStatus status) throws JavaModelException{
		pm.beginTask("", 5); //$NON-NLS-1$
		try{
			TextChangeManager changeManager= new TextChangeManager();
			addUpdates(changeManager, new SubProgressMonitor(pm, 4), status);
			addImportRewriteUpdates(changeManager);
			return changeManager;
		} catch (JavaModelException e){
			throw e;
		} catch (CoreException e){
			throw new JavaModelException(e);
		} finally{
			pm.done();
		}

	}

	private void addImportRewriteUpdates(TextChangeManager changeManager) throws CoreException {
		for (Iterator<ICompilationUnit> iter= fImportRewrites.keySet().iterator(); iter.hasNext();) {
			ICompilationUnit cu= iter.next();
			ImportRewrite importRewrite= fImportRewrites.get(cu);
			if (importRewrite != null && importRewrite.hasRecordedChanges()) {
				TextChangeCompatibility.addTextEdit(changeManager.get(cu), RefactoringCoreMessages.MoveCuUpdateCreator_update_imports, importRewrite.rewriteImports(null));
			}
		}
	}

	private void addUpdates(TextChangeManager changeManager, IProgressMonitor pm, RefactoringStatus status) throws CoreException {
		pm.beginTask("", fCus.length);  //$NON-NLS-1$
		for (int i= 0; i < fCus.length; i++){
			if (pm.isCanceled())
				throw new OperationCanceledException();

			addUpdates(changeManager, fCus[i], new SubProgressMonitor(pm, 1), status);
		}
	}

	private void addUpdates(TextChangeManager changeManager, ICompilationUnit movedUnit, IProgressMonitor pm, RefactoringStatus status) throws CoreException{
		try{
			pm.beginTask("", 3);  //$NON-NLS-1$
		  	pm.subTask(Messages.format(RefactoringCoreMessages.MoveCuUpdateCreator_searching, BasicElementLabels.getFileName(movedUnit)));

			if (isInAnotherFragmentOfSamePackage(movedUnit, fDestination)){
				pm.worked(3);
				return;
			}

		  	addImportToSourcePackageTypes(movedUnit, new SubProgressMonitor(pm, 1));
			removeImportsToDestinationPackageTypes(movedUnit);
			addReferenceUpdates(changeManager, movedUnit, new SubProgressMonitor(pm, 2), status);
		} finally{
			pm.done();
		}
	}

	private void addReferenceUpdates(TextChangeManager changeManager, ICompilationUnit movedUnit, IProgressMonitor pm, RefactoringStatus status) throws JavaModelException, CoreException {
		List<ICompilationUnit> cuList= Arrays.asList(fCus);
		SearchResultGroup[] references= getReferences(movedUnit, pm, status);
		for (int i= 0; i < references.length; i++) {
			SearchResultGroup searchResultGroup= references[i];
			ICompilationUnit referencingCu= searchResultGroup.getCompilationUnit();
			if (referencingCu == null)
				continue;

			boolean simpleReferencesNeedNewImport= simpleReferencesNeedNewImport(movedUnit, referencingCu, cuList);
			SearchMatch[] results= searchResultGroup.getSearchResults();
			for (int j= 0; j < results.length; j++) {
				// TODO: should update type references with results from addImport
				TypeReference reference= (TypeReference) results[j];
				if (reference.isImportDeclaration()) {
					ImportRewrite rewrite= getImportRewrite(referencingCu);
					IImportDeclaration importDecl= (IImportDeclaration) SearchUtils.getEnclosingJavaElement(results[j]);
					if (Flags.isStatic(importDecl.getFlags())) {
						rewrite.removeStaticImport(importDecl.getElementName());
						addStaticImport(movedUnit, importDecl, rewrite);
					} else {
						rewrite.removeImport(importDecl.getElementName());
						rewrite.addImport(createStringForNewImport(movedUnit, importDecl));
					}
				} else if (reference.isQualified()) {
					TextChange textChange= changeManager.get(referencingCu);
					String changeName= RefactoringCoreMessages.MoveCuUpdateCreator_update_references;
					TextEdit replaceEdit= new ReplaceEdit(reference.getOffset(), reference.getSimpleNameStart() - reference.getOffset(), fNewPackage);
					TextChangeCompatibility.addTextEdit(textChange, changeName, replaceEdit);
				} else if (simpleReferencesNeedNewImport) {
					ImportRewrite importEdit= getImportRewrite(referencingCu);
					String typeName= reference.getSimpleName();
					importEdit.addImport(getQualifiedType(fDestination.getElementName(), typeName));
				}
			}
		}
	}

	private void addStaticImport(ICompilationUnit movedUnit, IImportDeclaration importDecl, ImportRewrite rewrite) {
		String old= importDecl.getElementName();
		int oldPackLength= movedUnit.getParent().getElementName().length();

		StringBuffer result= new StringBuffer(fDestination.getElementName());
		if (oldPackLength == 0) // move FROM default package
			result.append('.').append(old);
		else if (result.length() == 0) // move TO default package
			result.append(old.substring(oldPackLength + 1)); // cut "."
		else
			result.append(old.substring(oldPackLength));
		int index= result.lastIndexOf("."); //$NON-NLS-1$
		if (index > 0 && index < result.length() - 1)
			rewrite.addStaticImport(result.substring(0, index), result.substring(index + 1, result.length()), true);
	}

	private String getQualifiedType(String packageName, String typeName) {
		if (packageName.length() == 0)
			return typeName;
		else
			return packageName + '.' + typeName;
	}

    private String createStringForNewImport(ICompilationUnit movedUnit, IImportDeclaration importDecl) {
    	String old= importDecl.getElementName();
		int oldPackLength= movedUnit.getParent().getElementName().length();

		StringBuffer result= new StringBuffer(fDestination.getElementName());
		if (oldPackLength == 0) // move FROM default package
			result.append('.').append(old);
		else if (result.length() == 0) // move TO default package
			result.append(old.substring(oldPackLength + 1)); // cut "."
		else
			result.append(old.substring(oldPackLength));
		return result.toString();
    }

	private void removeImportsToDestinationPackageTypes(ICompilationUnit movedUnit) throws CoreException{
		ImportRewrite importEdit= getImportRewrite(movedUnit);
		IType[] destinationTypes= getDestinationPackageTypes();
		for (int i= 0; i < destinationTypes.length; i++) {
			importEdit.removeImport(destinationTypes[i].getFullyQualifiedName('.'));
		}
	}

	private IType[] getDestinationPackageTypes() throws JavaModelException {
		List<IType> types= new ArrayList<>();
		if (fDestination.exists()) {
			ICompilationUnit[] cus= fDestination.getCompilationUnits();
			for (int i= 0; i < cus.length; i++) {
				types.addAll(Arrays.asList(cus[i].getAllTypes()));
			}
		}
		return types.toArray(new IType[types.size()]);
	}

	private void addImportToSourcePackageTypes(ICompilationUnit movedUnit, IProgressMonitor pm) throws CoreException{
		List<ICompilationUnit> cuList= Arrays.asList(fCus);
		IType[] allCuTypes= movedUnit.getAllTypes();
		IType[] referencedTypes= ReferenceFinderUtil.getTypesReferencedIn(allCuTypes, pm);
		ImportRewrite importEdit= getImportRewrite(movedUnit);
		importEdit.setFilterImplicitImports(false);
		IPackageFragment srcPack= (IPackageFragment)movedUnit.getParent();
		for (int i= 0; i < referencedTypes.length; i++) {
				IType iType= referencedTypes[i];
				if (! iType.exists())
					continue;
				if (!JavaModelUtil.isSamePackage(iType.getPackageFragment(), srcPack))
					continue;
				if (cuList.contains(iType.getCompilationUnit()))
					continue;
				importEdit.addImport(iType.getFullyQualifiedName('.'));
		}
	}

	private ImportRewrite getImportRewrite(ICompilationUnit cu) throws CoreException{
		if (fImportRewrites.containsKey(cu))
			return fImportRewrites.get(cu);
		ImportRewrite importEdit= StubUtility.createImportRewrite(cu, true);
		fImportRewrites.put(cu, importEdit);
		return importEdit;
	}

	private boolean simpleReferencesNeedNewImport(ICompilationUnit movedUnit, ICompilationUnit referencingCu, List<ICompilationUnit> cuList) {
		if (referencingCu.equals(movedUnit))
			return false;
		if (cuList.contains(referencingCu))
			return false;
		if (isReferenceInAnotherFragmentOfSamePackage(referencingCu, movedUnit)) {
			/* Destination package is different from source, since
			 * isDestinationAnotherFragmentOfSamePackage(movedUnit) was false in addUpdates(.) */
			return true;
		}

		//heuristic
		if (referencingCu.getImport(movedUnit.getParent().getElementName() + ".*").exists()) //$NON-NLS-1$
			return true; // has old star import
		if (referencingCu.getParent().equals(movedUnit.getParent()))
			return true; //is moved away from same package
		return false;
	}

	private boolean isReferenceInAnotherFragmentOfSamePackage(ICompilationUnit referencingCu, ICompilationUnit movedUnit) {
		if (referencingCu == null)
			return false;
		if (! (referencingCu.getParent() instanceof IPackageFragment))
			return false;
		IPackageFragment pack= (IPackageFragment) referencingCu.getParent();
		return isInAnotherFragmentOfSamePackage(movedUnit, pack);
	}

	private static boolean isInAnotherFragmentOfSamePackage(ICompilationUnit cu, IPackageFragment pack) {
		if (! (cu.getParent() instanceof IPackageFragment))
			return false;
		IPackageFragment cuPack= (IPackageFragment) cu.getParent();
		return ! cuPack.equals(pack) && JavaModelUtil.isSamePackage(cuPack, pack);
	}

	private static SearchResultGroup[] getReferences(ICompilationUnit unit, IProgressMonitor pm, RefactoringStatus status) throws CoreException {
		final SearchPattern pattern= RefactoringSearchEngine.createOrPattern(unit.getTypes(), IJavaSearchConstants.REFERENCES);
		if (pattern != null) {
			String binaryRefsDescription= Messages.format(RefactoringCoreMessages.ReferencesInBinaryContext_ref_in_binaries_description , BasicElementLabels.getFileName(unit));
			ReferencesInBinaryContext binaryRefs= new ReferencesInBinaryContext(binaryRefsDescription);
			Collector requestor= new Collector(((IPackageFragment) unit.getParent()), binaryRefs);
			IJavaSearchScope scope= RefactoringScopeFactory.create(unit, true, false);

			SearchResultGroup[] result= RefactoringSearchEngine.search(pattern, scope, requestor, new SubProgressMonitor(pm, 1), status);
			binaryRefs.addErrorIfNecessary(status);
			return result;
		}
		return new SearchResultGroup[] {};
	}

	private final static class Collector extends CollectingSearchRequestor {
		private IPackageFragment fSource;
		private IScanner fScanner;

		public Collector(IPackageFragment source, ReferencesInBinaryContext binaryRefs) {
			super(binaryRefs);
			fSource= source;
			fScanner= ToolFactory.createScanner(false, false, false, false);
		}

		@Override
		public void acceptSearchMatch(SearchMatch match) throws CoreException {
			if (filterMatch(match))
				return;

			/*
			 * Processing is done in collector to reuse the buffer which was
			 * already required by the search engine to locate the matches.
			 */
			// [start, end[ include qualification.
			IJavaElement element= SearchUtils.getEnclosingJavaElement(match);
			int accuracy= match.getAccuracy();
			int start= match.getOffset();
			int length= match.getLength();
			boolean insideDocComment= match.isInsideDocComment();
			IResource res= match.getResource();
			if (element.getAncestor(IJavaElement.IMPORT_DECLARATION) != null) {
				collectMatch(TypeReference.createImportReference(element, accuracy, start, length, insideDocComment, res));
			} else {
				ICompilationUnit unit= (ICompilationUnit) element.getAncestor(IJavaElement.COMPILATION_UNIT);
				if (unit != null) {
					IBuffer buffer= unit.getBuffer();
					String matchText= buffer.getText(start, length);
					if (fSource.isDefaultPackage()) {
						collectMatch(TypeReference.createSimpleReference(element, accuracy, start, length, insideDocComment, res, matchText));
					} else {
						// assert: matchText doesn't start nor end with comment
						int simpleNameStart= getLastSimpleNameStart(matchText);
						if (simpleNameStart != 0) {
							collectMatch(TypeReference.createQualifiedReference(element, accuracy, start, length, insideDocComment, res, start + simpleNameStart));
						} else {
							collectMatch(TypeReference.createSimpleReference(element, accuracy, start, length, insideDocComment, res, matchText));
						}
					}
				}
			}
		}

		private int getLastSimpleNameStart(String reference) {
			fScanner.setSource(reference.toCharArray());
			int lastIdentifierStart= -1;
			try {
				int tokenType= fScanner.getNextToken();
				while (tokenType != ITerminalSymbols.TokenNameEOF) {
					if (tokenType == ITerminalSymbols.TokenNameIdentifier)
						lastIdentifierStart= fScanner.getCurrentTokenStartPosition();
					tokenType= fScanner.getNextToken();
				}
			} catch (InvalidInputException e) {
				JavaPlugin.log(e);
			}
			return lastIdentifierStart;
		}
	}


	private final static class TypeReference extends TypeReferenceMatch {
		private String fSimpleTypeName;
		private int fSimpleNameStart;

		private TypeReference(IJavaElement enclosingElement, int accuracy, int start, int length,
				boolean insideDocComment, IResource resource, int simpleNameStart, String simpleName) {
			super(enclosingElement, accuracy, start, length,
					insideDocComment, SearchEngine.getDefaultSearchParticipant(), resource);
			fSimpleNameStart= simpleNameStart;
			fSimpleTypeName= simpleName;
		}

		public static TypeReference createQualifiedReference(IJavaElement enclosingElement, int accuracy, int start, int length,
				boolean insideDocComment, IResource resource, int simpleNameStart) {
			Assert.isTrue(start < simpleNameStart && simpleNameStart < start + length);
			return new TypeReference(enclosingElement, accuracy, start, length, insideDocComment, resource, simpleNameStart, null);
		}

		public static TypeReference createImportReference(IJavaElement enclosingElement, int accuracy, int start, int length,
				boolean insideDocComment, IResource resource) {
			return new TypeReference(enclosingElement, accuracy, start, length, insideDocComment, resource, -1, null);
		}

		public static TypeReference createSimpleReference(IJavaElement enclosingElement, int accuracy, int start, int length,
				boolean insideDocComment, IResource resource, String simpleName) {
			return new TypeReference(enclosingElement, accuracy, start, length, insideDocComment, resource, -1, simpleName);
		}

		public boolean isImportDeclaration() {
			return SearchUtils.getEnclosingJavaElement(this).getAncestor(IJavaElement.IMPORT_DECLARATION) != null;
		}

		public boolean isQualified() {
			return fSimpleNameStart != -1;
		}

		/**
		 * @return start offset of simple type name, or -1 iff ! isQualified()
		 */
		public int getSimpleNameStart() {
			return fSimpleNameStart;
		}

		/**
		 * @return simple type name, or null iff ! isSimpleName()
		 */
		public String getSimpleName() {
			return fSimpleTypeName;
		}
	}

}
