/*******************************************************************************
 * Copyright (c) 2007, 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.ltk.internal.core.refactoring.resource;

import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;

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.IResourceVisitor;
import org.eclipse.core.resources.mapping.IResourceChangeDescriptionFactory;

import org.eclipse.core.filebuffers.FileBuffers;
import org.eclipse.core.filebuffers.ITextFileBuffer;
import org.eclipse.core.filebuffers.LocationKind;

import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.RefactoringChangeDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext;
import org.eclipse.ltk.core.refactoring.participants.DeleteArguments;
import org.eclipse.ltk.core.refactoring.participants.DeleteParticipant;
import org.eclipse.ltk.core.refactoring.participants.DeleteProcessor;
import org.eclipse.ltk.core.refactoring.participants.ParticipantManager;
import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant;
import org.eclipse.ltk.core.refactoring.participants.ResourceChangeChecker;
import org.eclipse.ltk.core.refactoring.participants.SharableParticipants;
import org.eclipse.ltk.core.refactoring.resource.DeleteResourceChange;
import org.eclipse.ltk.core.refactoring.resource.DeleteResourcesDescriptor;
import org.eclipse.ltk.internal.core.refactoring.BasicElementLabels;
import org.eclipse.ltk.internal.core.refactoring.Messages;
import org.eclipse.ltk.internal.core.refactoring.RefactoringCoreMessages;
import org.eclipse.ltk.internal.core.refactoring.Resources;

/**
 * A delete processor for {@link IResource resources}. The processor will delete the resources and
 * load delete participants if references should be deleted as well.
 *
 * @since 3.4
 */
public class DeleteResourcesProcessor extends DeleteProcessor {
	private IResource[] fResources;
	private boolean fDeleteContents;

	/**
	 * Create a new delete processor.  Same as DeleteResourcesProcessor(resources, true, false)
	 * @param resources the resources to delete.  They can be either {@link IProject} or {@link IFile} and {@link IFolder}.
	 */
	public DeleteResourcesProcessor(IResource[] resources) {
		this(resources, false);
	}

	/**
	 * Create a new delete processor.
	 * @param resources the resources to delete.  They can be either {@link IProject} or {@link IFile} and {@link IFolder}.
	 * @param deleteContents <code>true</code> if this will delete the project contents.  The content delete is not undoable.
	 */
	public DeleteResourcesProcessor(IResource[] resources, boolean deleteContents) {
		fResources= removeDescendants(resources);
		fDeleteContents= deleteContents;
	}

	/**
	 * Returns the resources to delete.
	 *
	 * @return the resources to delete.
	 */
	public IResource[] getResourcesToDelete() {
		return fResources;
	}

	/**
	 * Delete projects contents.
	 * @return <code>true</code> if this will delete the project contents.  The content delete is not undoable.
	 */
	public boolean isDeleteContents() {
		return fDeleteContents;
	}

	/**
	 * Set to delete the projects content.
	 * @param deleteContents <code>true</code> if this will delete the project contents.  The content delete is not undoable.
	 */
	public void setDeleteContents(boolean deleteContents) {
		fDeleteContents= deleteContents;
	}

	@Override
	public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		// allow only projects or only non-projects to be selected;
		// note that the selection may contain multiple types of resource
		if (!(Resources.containsOnlyProjects(fResources) || Resources.containsOnlyNonProjects(fResources))) {
			return RefactoringStatus.createFatalErrorStatus(RefactoringCoreMessages.DeleteResourcesProcessor_delete_error_mixed_types);
		}
	
		return new RefactoringStatus();
	}

	@Override
	public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException, OperationCanceledException {
		pm.beginTask("", 1); //$NON-NLS-1$
		try {
			RefactoringStatus result= new RefactoringStatus();

			for (int i= 0; i < fResources.length; i++) {
				IResource resource= fResources[i];
				if (!isSynchronizedExcludingLinkedResources(resource)) {
					String pathLabel= BasicElementLabels.getPathLabel(resource.getFullPath(), false);
					
					String locationLabel= null;
					IPath location= resource.getLocation();
					if (location != null) {
						locationLabel= BasicElementLabels.getPathLabel(location, true);
					} else {
						URI uri= resource.getLocationURI();
						if (uri != null) {
							locationLabel= BasicElementLabels.getURLPart(uri.toString());
						}
					}

					String warning;
					if (resource instanceof IFile) {
						if (locationLabel != null) {
							warning= Messages.format(RefactoringCoreMessages.DeleteResourcesProcessor_warning_out_of_sync_file_loc, new Object[] { pathLabel, locationLabel });
						} else {
							warning= Messages.format(RefactoringCoreMessages.DeleteResourcesProcessor_warning_out_of_sync_file, pathLabel);
						}
					} else {
						if (locationLabel != null) {
							warning= Messages.format(RefactoringCoreMessages.DeleteResourcesProcessor_warning_out_of_sync_container_loc, new Object[] { pathLabel, locationLabel });
						} else {
							warning= Messages.format(RefactoringCoreMessages.DeleteResourcesProcessor_warning_out_of_sync_container, pathLabel);
						}
					}
					result.addWarning(warning);
				}
			}

			checkDirtyResources(result);
			
			ResourceChangeChecker checker= context.getChecker(ResourceChangeChecker.class);
			IResourceChangeDescriptionFactory deltaFactory= checker.getDeltaFactory();
			for (int i= 0; i < fResources.length; i++) {
				if (fResources[i].isPhantom()) {
					result.addFatalError(Messages.format(RefactoringCoreMessages.DeleteResourcesProcessor_delete_error_phantom, BasicElementLabels.getPathLabel(fResources[i].getFullPath(), false)));
				} else if (fDeleteContents && Resources.isReadOnly(fResources[i])) {
					result.addFatalError(Messages.format(RefactoringCoreMessages.DeleteResourcesProcessor_delete_error_read_only, BasicElementLabels.getPathLabel(fResources[i].getFullPath(), false)));
				} else {
					deltaFactory.delete(fResources[i]);
				}
			}
			return result;
		} finally {
			pm.done();
		}
	}

	/**
	 * Checks whether this resource and its descendents are considered to be in sync with the local
	 * file system. The linked resources and their descendents are excluded from the check.
	 * 
	 * @param resource the resource to check
	 * @return <code>true</code> if this resource and its descendents except linked resources are
	 *         synchronized, and <code>false</code> in all other cases
	 * @throws CoreException if visiting the resource descendents fails for any reason
	 * @see IResource#isSynchronized(int)
	 */
	public boolean isSynchronizedExcludingLinkedResources(IResource resource) throws CoreException {
		boolean[] result= { true };
		resource.accept(new IResourceVisitor() {
			@Override
			public boolean visit(IResource visitedResource) throws CoreException {
				if (!result[0] || visitedResource.isLinked())
					return false;
				if (!visitedResource.isSynchronized(IResource.DEPTH_ZERO)) {
					result[0]= false;
					return false;
				}
				return true;
			}
		}, IResource.DEPTH_INFINITE, IContainer.DO_NOT_CHECK_EXISTENCE);
		return result[0];
	}

	private void checkDirtyResources(final RefactoringStatus result) throws CoreException {
		for (int i= 0; i < fResources.length; i++) {
			IResource resource= fResources[i];
			if (resource instanceof IProject && !((IProject) resource).isOpen())
				continue;
			resource.accept(new IResourceVisitor() {
				@Override
				public boolean visit(IResource visitedResource) throws CoreException {
					if (visitedResource instanceof IFile) {
						checkDirtyFile(result, (IFile)visitedResource);
					}
					return true;
				}
			}, IResource.DEPTH_INFINITE, false);
		}
	}

	private void checkDirtyFile(RefactoringStatus result, IFile file) {
		if (!file.exists())
			return;
		ITextFileBuffer buffer= FileBuffers.getTextFileBufferManager().getTextFileBuffer(file.getFullPath(), LocationKind.IFILE);
		if (buffer != null && buffer.isDirty()) {
			String message= RefactoringCoreMessages.DeleteResourcesProcessor_warning_unsaved_file;
			if (buffer.isStateValidated() && buffer.isSynchronized()) {
				result.addWarning(Messages.format(message, BasicElementLabels.getPathLabel(file.getFullPath(), false)));
			} else {
				result.addFatalError(Messages.format(message, BasicElementLabels.getPathLabel(file.getFullPath(), false)));
			}
		}
	}

	@Override
	public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException {
		pm.beginTask(RefactoringCoreMessages.DeleteResourcesProcessor_create_task, fResources.length);
		try {
			RefactoringChangeDescriptor descriptor= new RefactoringChangeDescriptor(createDescriptor());
			CompositeChange change= new CompositeChange(RefactoringCoreMessages.DeleteResourcesProcessor_change_name);
			change.markAsSynthetic();
			for (int i= 0; i < fResources.length; i++) {
				pm.worked(1);
				DeleteResourceChange dc= new DeleteResourceChange(fResources[i].getFullPath(), true, fDeleteContents);
				dc.setDescriptor(descriptor);
				change.add(dc);
			}
			return change;
		} finally {
			pm.done();
		}
	}

	protected DeleteResourcesDescriptor createDescriptor() {
		DeleteResourcesDescriptor descriptor= new DeleteResourcesDescriptor();
		descriptor.setProject(null);
		descriptor.setDescription(getDeleteDescription());
		descriptor.setComment(descriptor.getDescription());
		descriptor.setFlags(RefactoringDescriptor.STRUCTURAL_CHANGE | RefactoringDescriptor.MULTI_CHANGE | RefactoringDescriptor.BREAKING_CHANGE);

		descriptor.setDeleteContents(fDeleteContents);
		descriptor.setResources(fResources);
		return descriptor;
	}

	private String getDeleteDescription() {
		if (fResources.length == 1) {
			return Messages.format(RefactoringCoreMessages.DeleteResourcesProcessor_description_single, BasicElementLabels.getPathLabel(fResources[0].getFullPath(), false));
		}
		return Messages.format(RefactoringCoreMessages.DeleteResourcesProcessor_description_multi, new Integer(fResources.length));
	}

	@Override
	public Object[] getElements() {
		return fResources;
	}

	@Override
	public String getIdentifier() {
		return "org.eclipse.ltk.core.refactoring.deleteResourcesProcessor"; //$NON-NLS-1$
	}

	@Override
	public String getProcessorName() {
		return RefactoringCoreMessages.DeleteResourcesProcessor_processor_name;
	}

	@Override
	public boolean isApplicable() throws CoreException {
		for (int i= 0; i < fResources.length; i++) {
			if (!canDelete(fResources[i])) {
				return false;
			}
		}
		return true;
	}

	private boolean canDelete(IResource res) {
		return res.isAccessible() && !res.isPhantom();
	}

	@Override
	public RefactoringParticipant[] loadParticipants(RefactoringStatus status, SharableParticipants sharedParticipants) throws CoreException {
		final ArrayList<DeleteParticipant> result= new ArrayList<>();
		if (!isApplicable()) {
			return new RefactoringParticipant[0];
		}

		final String[] affectedNatures= ResourceProcessors.computeAffectedNatures(fResources);
		final DeleteArguments deleteArguments= new DeleteArguments(fDeleteContents);
		for (int i= 0; i < fResources.length; i++) {
			result.addAll(Arrays.asList(ParticipantManager.loadDeleteParticipants(status, this, fResources[i], deleteArguments, affectedNatures, sharedParticipants)));
		}

		return result.toArray(new RefactoringParticipant[result.size()]);
	}

	private static IResource[] removeDescendants(IResource[] resources) {
		ArrayList<IResource> result= new ArrayList<>();
		for (int i= 0; i < resources.length; i++) {
			addToList(result, resources[i]);
		}
		return result.toArray(new IResource[result.size()]);
	}

	private static void addToList(ArrayList<IResource> result, IResource curr) {
		IPath currPath= curr.getFullPath();
		for (int k= result.size() - 1; k >= 0 ; k--) {
			IResource other= result.get(k);
			IPath otherPath= other.getFullPath();
			if (otherPath.isPrefixOf(currPath)) {
				return; // current entry is a descendant of an entry in the list
			}
			if (currPath.isPrefixOf(otherPath)) {
				result.remove(k); // entry in the list is a descendant of the current entry
			}
		}
		result.add(curr);
	}


}
