/*******************************************************************************
 * Copyright (c) 2000, 2018 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.corext.refactoring.reorg;

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

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.IWorkspaceRoot;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.dltk.core.IMember;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.ISourceManipulation;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.ISourceRange;
import org.eclipse.dltk.internal.corext.refactoring.Checks;
import org.eclipse.dltk.internal.corext.refactoring.RefactoringCoreMessages;
import org.eclipse.dltk.internal.corext.refactoring.changes.DeleteFileChange;
import org.eclipse.dltk.internal.corext.refactoring.changes.DeleteFolderChange;
import org.eclipse.dltk.internal.corext.refactoring.changes.DeleteFromBuildpathChange;
import org.eclipse.dltk.internal.corext.refactoring.changes.DeleteProjectFragmentChange;
import org.eclipse.dltk.internal.corext.refactoring.changes.DeleteSourceManipulationChange;
import org.eclipse.dltk.internal.corext.refactoring.changes.DynamicValidationStateChange;
import org.eclipse.dltk.internal.corext.refactoring.util.TextChangeManager;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CompositeChange;
import org.eclipse.ltk.core.refactoring.NullChange;
import org.eclipse.ltk.core.refactoring.TextFileChange;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.MultiTextEdit;

class DeleteChangeCreator {
	private DeleteChangeCreator() {
		// private
	}

	static Change createDeleteChange(TextChangeManager manager,
			IResource[] resources, IModelElement[] modelElements,
			String changeName) throws CoreException {
		final DynamicValidationStateChange result = new DynamicValidationStateChange(
				changeName) {
			@Override
			public Change perform(IProgressMonitor pm) throws CoreException {
				super.perform(pm);
				return null;
			}
		};
		for (int i = 0; i < modelElements.length; i++) {
			IModelElement element = modelElements[i];
			if (!ReorgUtils.isInsideSourceModule(element))
				result.add(createDeleteChange(element));
		}

		for (int i = 0; i < resources.length; i++) {
			result.add(createDeleteChange(resources[i]));
		}

		Map grouped = ReorgUtils
				.groupBySourceModule(getElementsSmallerThanCu(modelElements));
		if (grouped.size() != 0) {
			Assert.isNotNull(manager);
			for (Iterator iter = grouped.keySet().iterator(); iter.hasNext();) {
				ISourceModule cu = (ISourceModule) iter.next();
				Change change = createDeleteChange(cu, (List) grouped.get(cu),
						manager);
				if (change != null) {
					result.add(change);
				}
			}
		}

		return result;
	}

	private static Change createDeleteChange(IResource resource) {
		Assert.isTrue(!(resource instanceof IWorkspaceRoot));// cannot be done
		Assert.isTrue(!(resource instanceof IProject)); // project deletion is
														// handled by the
														// workbench
		if (resource instanceof IFile)
			return new DeleteFileChange((IFile) resource, true);
		if (resource instanceof IFolder)
			return new DeleteFolderChange((IFolder) resource, true);
		Assert.isTrue(false);// there're no more kinds
		return null;
	}

	/*
	 * List<IModelElement> modelElements
	 */
	private static Change createDeleteChange(ISourceModule cu,
			List<IModelElement> modelElements, TextChangeManager manager)
			throws CoreException {
//		SourceModule cuNode= RefactoringASTParser.parseWithASTProvider(cu, false, null);
//		SourceModuleRewrite rewriter= new SourceModuleRewrite(cu, cuNode);
		Assert.isNotNull(cu);
		Assert.isNotNull(modelElements);
		Assert.isNotNull(manager);
		TextFileChange textFileChange = null;
		if (cu != null && cu.getResource() instanceof IFile) {
			textFileChange = new TextFileChange(cu.getElementName(),
					(IFile) cu.getResource());
			MultiTextEdit fileChangeRootEdit = new MultiTextEdit();
			textFileChange.setEdit(fileChangeRootEdit);

			manager.manage(cu, textFileChange);

			IModelElement[] elements = modelElements
					.toArray(new IModelElement[modelElements.size()]);

			for (int cnt = 0, max = elements.length; cnt < max; cnt++) {
				ISourceRange sourceRange = null;
				if (elements[cnt] instanceof IMember) {
					IMember type = (IMember) elements[cnt];
					sourceRange = type.getSourceRange();
				}
				if (sourceRange != null) {
					DeleteEdit edit = new DeleteEdit(sourceRange.getOffset(),
							sourceRange.getLength());

					fileChangeRootEdit.addChild(edit);
					if (cu.isWorkingCopy()) {
						textFileChange.setSaveMode(TextFileChange.LEAVE_DIRTY);
					}

				}
			}
		}

		// ASTNodeDeleteUtil.markAsDeleted(elements, rewriter, null);
//		return addTextEditFromRewrite(manager, cu, rewriter.getASTRewrite());
		return textFileChange;
	}

//	private static TextChange addTextEditFromRewrite(TextChangeManager manager, ISourceModule cu, ASTRewrite rewrite) throws CoreException {
//		try {
//			ITextFileBuffer buffer= RefactoringFileBuffers.acquire(cu);
//			TextEdit resultingEdits= rewrite.rewriteAST(buffer.getDocument(), cu.getScriptProject().getOptions(true));
//			TextChange textChange= manager.get(cu);
//			if (textChange instanceof TextFileChange) {
//				TextFileChange tfc= (TextFileChange) textChange;
//				if (cu.isWorkingCopy())
//					tfc.setSaveMode(TextFileChange.LEAVE_DIRTY);
//			}
//			String message= RefactoringCoreMessages.DeleteChangeCreator_1;
//			TextChangeCompatibility.addTextEdit(textChange, message, resultingEdits);
//			return textChange;
//		} finally {
//			RefactoringFileBuffers.release(cu);
//		}
//	}

	// List<IModelElement>
	private static List getElementsSmallerThanCu(
			IModelElement[] modelElements) {
		List result = new ArrayList();
		for (int i = 0; i < modelElements.length; i++) {
			IModelElement element = modelElements[i];
			if (ReorgUtils.isInsideSourceModule(element))
				result.add(element);
		}
		return result;
	}

	private static Change createDeleteChange(IModelElement modelElement) {
		Assert.isTrue(!ReorgUtils.isInsideSourceModule(modelElement));

		switch (modelElement.getElementType()) {
		case IModelElement.PROJECT_FRAGMENT:
			return createProjectFragmentDeleteChange(
					(IProjectFragment) modelElement);

		case IModelElement.SCRIPT_FOLDER:
			return createSourceManipulationDeleteChange(
					(IScriptFolder) modelElement);

		case IModelElement.SOURCE_MODULE:
			return createSourceManipulationDeleteChange(
					(ISourceModule) modelElement);

		case IModelElement.SCRIPT_MODEL: // cannot be done
			Assert.isTrue(false);
			return null;

		case IModelElement.SCRIPT_PROJECT: // handled differently
			Assert.isTrue(false);
			return null;

		case IModelElement.TYPE:
		case IModelElement.FIELD:
		case IModelElement.METHOD:
//			case IModelElement.INITIALIZER:
//			case IModelElement.PACKAGE_DECLARATION:
//			case IModelElement.IMPORT_CONTAINER:
//			case IModelElement.IMPORT_DECLARATION:
//				Assert.isTrue(false);//not done here
		default:
			Assert.isTrue(false);// there's no more kinds
			return new NullChange();
		}
	}

	private static Change createSourceManipulationDeleteChange(
			ISourceManipulation element) {
		// XXX workaround for bug 31384, in case of linked ISourceManipulation
		// delete the resource
		if (element instanceof ISourceModule
				|| element instanceof IScriptFolder) {
			IResource resource;
			if (element instanceof ISourceModule)
				resource = ReorgUtils.getResource((ISourceModule) element);
			else
				resource = ((IScriptFolder) element).getResource();
			if (resource != null && resource.isLinked())
				return createDeleteChange(resource);
		}
		return new DeleteSourceManipulationChange(element, true);
	}

	private static Change createProjectFragmentDeleteChange(
			IProjectFragment root) {
		IResource resource = root.getResource();
		if (resource != null && resource.isLinked()) {
			// XXX using this code is a workaround for jcore bug 31998
			// jcore cannot handle linked stuff
			// normally, we should always create DeleteProjectFragmentChange
			CompositeChange composite = new DynamicValidationStateChange(
					RefactoringCoreMessages.DeleteRefactoring_delete_package_fragment_root);

			composite.add(new DeleteFromBuildpathChange(root));
			Assert.isTrue(!Checks.isBuildpathDelete(root));// checked in
															// preconditions
			composite.add(createDeleteChange(resource));

			return composite;
		}
		Assert.isTrue(!root.isExternal());
		// TODO remove the query argument
		return new DeleteProjectFragmentChange(root, true, null);
	}
}
