/*******************************************************************************
 * 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
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.core;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.core.IBuildpathEntry;
import org.eclipse.dltk.core.IModelStatus;
import org.eclipse.dltk.core.IModelStatusConstants;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptModel;
import org.eclipse.dltk.core.IScriptProject;
import org.eclipse.dltk.core.ModelException;


public class DeleteProjectFragmentOperation extends ModelOperation {

	int updateResourceFlags;
	int updateModelFlags;

	public DeleteProjectFragmentOperation(
		IProjectFragment root,
		int updateResourceFlags,
		int updateModelFlags) {
			
		super(root);
		this.updateResourceFlags = updateResourceFlags;
		this.updateModelFlags = updateModelFlags;
	}

	@Override
	protected void executeOperation() throws ModelException {
		
		IProjectFragment root = (IProjectFragment)this.getElementToProcess();
		IBuildpathEntry rootEntry = root.getRawBuildpathEntry();
		
		// remember olds roots
		DeltaProcessor deltaProcessor = ModelManager.getModelManager().getDeltaProcessor();
		if (deltaProcessor.oldRoots == null)
			deltaProcessor.oldRoots = new HashMap<IScriptProject, IProjectFragment[]>();
		
		// update buildpath if needed
		if ((updateModelFlags & IProjectFragment.ORIGINATING_PROJECT_BUILDPATH) != 0) {
			updateProjectBuildpath(rootEntry.getPath(), root.getScriptProject(), deltaProcessor.oldRoots);
		}
		if ((updateModelFlags & IProjectFragment.OTHER_REFERRING_PROJECTS_BUILDPATH) != 0) {
			updateReferringProjectBuildpaths(rootEntry.getPath(), root.getScriptProject(), deltaProcessor.oldRoots);
		}
		
		// delete resource
		if (!root.isExternal() && (this.updateModelFlags & IProjectFragment.NO_RESOURCE_MODIFICATION) == 0) {
			deleteResource(root, rootEntry);
		}
	}

	protected void deleteResource(
		IProjectFragment root,
		IBuildpathEntry rootEntry)
		throws ModelException {
		final char[][] exclusionPatterns = ((BuildpathEntry)rootEntry).fullExclusionPatternChars();
		IResource rootResource = root.getResource();
		if (rootEntry.getEntryKind() != IBuildpathEntry.BPE_SOURCE || exclusionPatterns == null) {
			try {
				rootResource.delete(this.updateResourceFlags, progressMonitor);
			} catch (CoreException e) {
				throw new ModelException(e);
			}
		} else {
			final IPath[] nestedFolders = getNestedFolders(root);
			IResourceProxyVisitor visitor = new IResourceProxyVisitor() {
				@Override
				public boolean visit(IResourceProxy proxy) throws CoreException {
					if (proxy.getType() == IResource.FOLDER) {
						IPath path = proxy.requestFullPath();
						if (prefixesOneOf(path, nestedFolders)) {
							// equals if nested source folder
							return !equalsOneOf(path, nestedFolders);
						} else {
							// subtree doesn't contain any nested source folders
							proxy.requestResource().delete(updateResourceFlags, progressMonitor);
							return false;
						}
					} else {
						proxy.requestResource().delete(updateResourceFlags, progressMonitor);
						return false;
					}
				}
			};
			try {
				rootResource.accept(visitor, IResource.NONE);
			} catch (CoreException e) {
				throw new ModelException(e);
			}
		}
		this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE); 
	}


	/*
	 * Deletes the buildpath entries equals to the given rootPath from all Script projects.
	 */
	protected void updateReferringProjectBuildpaths(IPath rootPath,
			IScriptProject projectOfRoot,
			Map<IScriptProject, IProjectFragment[]> oldRoots)
			throws ModelException {
		IScriptModel model = this.getModel();
		IScriptProject[] projects = model.getScriptProjects();
		for (int i = 0, length = projects.length; i < length; i++) {
			IScriptProject project = projects[i];
			if (project.equals(projectOfRoot)) continue;
			updateProjectBuildpath(rootPath, project, oldRoots);
		}
	}

	/*
	 * Deletes the buildpath entries equals to the given rootPath from the given project.
	 */
	protected void updateProjectBuildpath(IPath rootPath,
			IScriptProject project,
			Map<IScriptProject, IProjectFragment[]> oldRoots)
			throws ModelException {
		// remember old roots
		oldRoots.put(project, project.getProjectFragments());
		
		IBuildpathEntry[] buildpath = project.getRawBuildpath();
		IBuildpathEntry[] newBuildpath = null;
		int cpLength = buildpath.length;
		int newCPIndex = -1;
		for (int j = 0; j < cpLength; j++) {
			IBuildpathEntry entry = buildpath[j];
			if (rootPath.equals(entry.getPath())) {
				if (newBuildpath == null) {
					newBuildpath = new IBuildpathEntry[cpLength-1];
					System.arraycopy(buildpath, 0, newBuildpath, 0, j);
					newCPIndex = j;
				}
			} else if (newBuildpath != null) {
				newBuildpath[newCPIndex++] = entry;
			}
		}
		if (newBuildpath != null) {
			if (newCPIndex < newBuildpath.length) {
				System.arraycopy(newBuildpath, 0, newBuildpath = new IBuildpathEntry[newCPIndex], 0, newCPIndex);
			}
			project.setRawBuildpath(newBuildpath, progressMonitor);
		}
	}	

	@Override
	protected IModelStatus verify() {
		IModelStatus status = super.verify();
		if (!status.isOK()) {
			return status;
		}
		IProjectFragment root = (IProjectFragment) this.getElementToProcess();
		if (root == null || !root.exists()) {
			return new ModelStatus(IModelStatusConstants.ELEMENT_DOES_NOT_EXIST, root);
		}

		IResource resource = root.getResource();
		if (resource instanceof IFolder) {
			if (resource.isLinked()) {
				return new ModelStatus(IModelStatusConstants.INVALID_RESOURCE, root);
			}
		}
		return ModelStatus.VERIFIED_OK;
	}

}
