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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;

import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.IParticipantDescriptorFilter;
import org.eclipse.ltk.core.refactoring.participants.MoveArguments;
import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
import org.eclipse.ltk.core.refactoring.participants.RefactoringArguments;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor;
import org.eclipse.ltk.core.refactoring.participants.RenameArguments;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
import org.eclipse.ltk.core.refactoring.participants.ValidateEditChecker;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.ILocalVariable;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.refactoring.RenameTypeArguments;

import org.eclipse.jdt.internal.corext.refactoring.participants.ResourceModifications;
import org.eclipse.jdt.internal.corext.refactoring.reorg.RefactoringModifications;


public class RenameModifications extends RefactoringModifications {

	private List<Object> fRename;
	private List<RefactoringArguments> fRenameArguments;
	private List<IParticipantDescriptorFilter> fParticipantDescriptorFilter;

	public RenameModifications() {
		fRename= new ArrayList<Object>();
		fRenameArguments= new ArrayList<RefactoringArguments>();
		fParticipantDescriptorFilter= new ArrayList<IParticipantDescriptorFilter>();
	}

	public void rename(IResource resource, RenameArguments args) {
		add(resource, args, null);
	}

	public void rename(IJavaProject project, RenameArguments args) {
		add(project, args, null);
		IProject rProject= project.getProject();
		if (rProject != null) {
			getResourceModifications().addRename(rProject, args);
			IProject[] referencingProjects= rProject.getReferencingProjects();
			for (int i= 0; i < referencingProjects.length; i++) {
				IFile classpath= getClasspathFile(referencingProjects[i]);
				if (classpath != null) {
					getResourceModifications().addChanged(classpath);
				}
			}
		}
	}

	public void rename(IPackageFragmentRoot sourceFolder, RenameArguments arguments) {
		add(sourceFolder, arguments, null);
		if (sourceFolder.getResource() != null) {
			getResourceModifications().addRename(sourceFolder.getResource(), arguments);
		}
	}

	public void rename(IPackageFragment rootPackage, RenameArguments args, boolean renameSubPackages) throws CoreException {
		add(rootPackage, args, null);
		IPackageFragment[] allSubPackages= null;
		if (renameSubPackages) {
			allSubPackages= getSubpackages(rootPackage);
			for (int i= 0; i < allSubPackages.length; i++) {
				IPackageFragment pack= allSubPackages[i];
				RenameArguments subArgs= new RenameArguments(
					getNewPackageName(rootPackage, args.getNewName(), pack.getElementName()),
					args.getUpdateReferences());
				add(pack, subArgs, null);
			}
		}
		IContainer container= (IContainer)rootPackage.getResource();
		if (container == null)
			return;
		IContainer target= (IContainer) ((IPackageFragmentRoot)rootPackage.getParent()).
			getPackageFragment(args.getNewName()).getResource();
		if ((!rootPackage.hasSubpackages() || renameSubPackages) && canMove(container, target)) {
			createIncludingParents(target.getParent());
			if (container.getParent().equals(target.getParent())) {
				getResourceModifications().addRename(container, new RenameArguments(target.getName(), args.getUpdateReferences()));
			} else {
				// This is a little tricky. The problem is that the refactoring participants
				// don't support a generic move like the resource API does. So for the delta
				// we generate one move, however for the participants we have to generate single
				// moves and deletes.
				try {
					getResourceModifications().ignoreForDelta();
					addAllResourceModifications(rootPackage, args, renameSubPackages, allSubPackages);
				} finally {
					getResourceModifications().trackForDelta();
				}
				getResourceModifications().addDelta(new ResourceModifications.MoveDescription(container, target.getFullPath()));
			}
		} else {
			addAllResourceModifications(rootPackage, args, renameSubPackages, allSubPackages);
		}
	}

	public void rename(ICompilationUnit unit, RenameArguments args) {
		add(unit, args, null);
		if (unit.getResource() != null) {
			getResourceModifications().addRename(unit.getResource(), new RenameArguments(args.getNewName(), args.getUpdateReferences()));
		}
	}

	public void rename(IType type, RenameTypeArguments args, IParticipantDescriptorFilter filter) {
		add(type, args, filter);
	}

	public void rename(IField field, RenameArguments args) {
		add(field, args, null);
	}

	public void rename(IMethod method, RenameArguments args) {
		add(method, args, null);
	}

	public void rename(ILocalVariable variable, RenameArguments args) {
		add(variable, args, null);
	}

	public void rename(ITypeParameter typeParameter, RenameArguments arguments) {
		add(typeParameter, arguments, null);
	}

	@Override
	public void buildDelta(IResourceChangeDescriptionFactory builder) {
		for (int i= 0; i < fRename.size(); i++) {
			Object element= fRename.get(i);
			if (element instanceof IResource) {
				ResourceModifications.buildMoveDelta(builder, (IResource) element, (RenameArguments) fRenameArguments.get(i));
			}
		}
		getResourceModifications().buildDelta(builder);
	}

	@Override
	public void buildValidateEdits(ValidateEditChecker checker) {
		for (Iterator<Object> iter= fRename.iterator(); iter.hasNext();) {
			Object element= iter.next();
			if (element instanceof ICompilationUnit) {
				ICompilationUnit unit= (ICompilationUnit)element;
				IResource resource= unit.getResource();
				if (resource != null && resource.getType() == IResource.FILE) {
					checker.addFile((IFile)resource);
				}
			}
		}
	}

	@Override
	public RefactoringParticipant[] loadParticipants(RefactoringStatus status, RefactoringProcessor owner, String[] natures, SharableParticipants shared) {
		List<RefactoringParticipant> result= new ArrayList<RefactoringParticipant>();
		for (int i= 0; i < fRename.size(); i++) {
			result.addAll(Arrays.asList(ParticipantManager.loadRenameParticipants(status,
				owner, fRename.get(i),
				(RenameArguments) fRenameArguments.get(i),
				fParticipantDescriptorFilter.get(i),
				natures, shared)));
		}
		result.addAll(Arrays.asList(getResourceModifications().getParticipants(status, owner, natures, shared)));
		return result.toArray(new RefactoringParticipant[result.size()]);
	}

	private void add(Object element, RefactoringArguments args, IParticipantDescriptorFilter filter) {
		Assert.isNotNull(element);
		Assert.isNotNull(args);
		fRename.add(element);
		fRenameArguments.add(args);
		fParticipantDescriptorFilter.add(filter);
	}

	private void addAllResourceModifications(IPackageFragment rootPackage, RenameArguments args, boolean renameSubPackages, IPackageFragment[] allSubPackages) throws CoreException {
		IFolder target= addResourceModifications(rootPackage, args, rootPackage, renameSubPackages);
		if (renameSubPackages) {
			IContainer container= (IContainer) rootPackage.getResource();
			if (container == null)
				return;
			boolean removeContainer= ! container.contains(target);
			for (int i= 0; i < allSubPackages.length; i++) {
				IPackageFragment pack= allSubPackages[i];
				IFolder subTarget= addResourceModifications(rootPackage, args, pack, renameSubPackages);
				if (container.contains(subTarget))
					removeContainer= false;
			}
			if (removeContainer) {
				getResourceModifications().addDelete(container);
			}
		}
	}

	private IFolder addResourceModifications(IPackageFragment rootPackage, RenameArguments args, IPackageFragment pack, boolean renameSubPackages) throws CoreException {
		IContainer container= (IContainer)pack.getResource();
		if (container == null)
			return null;
		IFolder target= computeTargetFolder(rootPackage, args, pack);
		createIncludingParents(target);
		MoveArguments arguments= new MoveArguments(target, args.getUpdateReferences());
		IResource[] resourcesToMove= collectResourcesOfInterest(pack);
		Set<IResource> allMembers= new HashSet<IResource>(Arrays.asList(container.members()));
		for (int i= 0; i < resourcesToMove.length; i++) {
			IResource toMove= resourcesToMove[i];
			getResourceModifications().addMove(toMove, arguments);
			allMembers.remove(toMove);
		}
		for (Iterator<IResource> iter= allMembers.iterator(); iter.hasNext();) {
			IResource element= iter.next();
			if (element instanceof IFile) {
				getResourceModifications().addDelete(element);
				iter.remove();
			}
		}
		if (! renameSubPackages && allMembers.isEmpty()) {
			getResourceModifications().addDelete(container);
		}
		return target;
	}

	private boolean canMove(IContainer source, IContainer target) {
		return !target.exists() && !source.getFullPath().isPrefixOf(target.getFullPath());
	}

	private IPackageFragment[] getSubpackages(IPackageFragment pack) throws CoreException {
		IPackageFragmentRoot root= (IPackageFragmentRoot) pack.getParent();
		IJavaElement[] allPackages= root.getChildren();
		if (pack.isDefaultPackage())
			return new IPackageFragment[0];
		ArrayList<IPackageFragment> result= new ArrayList<IPackageFragment>();
		String prefix= pack.getElementName() + '.';
		for (int i= 0; i < allPackages.length; i++) {
			IPackageFragment currentPackage= (IPackageFragment) allPackages[i];
			if (currentPackage.getElementName().startsWith(prefix))
				result.add(currentPackage);
		}
		return result.toArray(new IPackageFragment[result.size()]);
	}

	private IFolder computeTargetFolder(IPackageFragment rootPackage, RenameArguments args, IPackageFragment pack) {
		IPath path= pack.getParent().getPath();
		path= path.append(getNewPackageName(rootPackage, args.getNewName(),  pack.getElementName()).replace('.', IPath.SEPARATOR));
		IFolder target= ResourcesPlugin.getWorkspace().getRoot().getFolder(path);
		return target;
	}

	private String getNewPackageName(IPackageFragment rootPackage, String newPackageName, String oldSubPackageName) {
		String oldPackageName= rootPackage.getElementName();
		return newPackageName + oldSubPackageName.substring(oldPackageName.length());
	}
}
