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

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.AssertionFailedException;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.core.DLTKLanguageManager;
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.IScriptProject;
import org.eclipse.dltk.core.ModelException;
import org.eclipse.dltk.internal.core.util.Messages;

public class CopyProjectFragmentOperation extends ModelOperation {
	IPath destination;
	int updateResourceFlags;
	int updateModelFlags;
	IBuildpathEntry sibling;

	public CopyProjectFragmentOperation(IProjectFragment root,
			IPath destination, int updateResourceFlags, int updateModelFlags,
			IBuildpathEntry sibling) {

		super(root);
		this.destination = destination;
		this.updateResourceFlags = updateResourceFlags;
		this.updateModelFlags = updateModelFlags;
		this.sibling = sibling;
	}

	@Override
	protected void executeOperation() throws ModelException {

		IProjectFragment root = (IProjectFragment) this.getElementToProcess();
		IBuildpathEntry rootEntry = root.getRawBuildpathEntry();
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();

		// copy resource
		if (!root.isExternal()
				&& (this.updateModelFlags & IProjectFragment.NO_RESOURCE_MODIFICATION) == 0) {
			copyResource(root, rootEntry, workspaceRoot);
		}

		// update buildpath if needed
		if ((this.updateModelFlags & IProjectFragment.DESTINATION_PROJECT_BUILDPATH) != 0) {
			addEntryToBuildpath(rootEntry, workspaceRoot);
		}
	}

	protected void copyResource(IProjectFragment root,
			IBuildpathEntry rootEntry, final IWorkspaceRoot workspaceRoot)
			throws ModelException {
		final char[][] exclusionPatterns = ((BuildpathEntry) rootEntry)
				.fullExclusionPatternChars();
		IResource rootResource = root.getResource();
		if (root.getKind() == IProjectFragment.K_BINARY
				|| exclusionPatterns == null) {
			try {
				IResource destRes;
				if ((this.updateModelFlags & IProjectFragment.REPLACE) != 0) {
					if (rootEntry.getPath().equals(this.destination))
						return;
					if ((destRes = workspaceRoot.findMember(this.destination)) != null) {
						destRes.delete(this.updateResourceFlags,
								progressMonitor);
					}
				}
				rootResource.copy(this.destination, this.updateResourceFlags,
						progressMonitor);
			} catch (CoreException e) {
				throw new ModelException(e);
			}
		} else {
			final int sourceSegmentCount = rootEntry.getPath().segmentCount();
			final IFolder destFolder = workspaceRoot
					.getFolder(this.destination);
			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)) {
							if (equalsOneOf(path, nestedFolders)) {
								// nested source folder
								return false;
							} else {
								// folder containing nested source folder
								IFolder folder = destFolder
										.getFolder(path
												.removeFirstSegments(sourceSegmentCount));
								if ((updateModelFlags & IProjectFragment.REPLACE) != 0
										&& folder.exists()) {
									return true;
								}
								folder.create(updateResourceFlags, true,
										progressMonitor);
								return true;
							}
						} else {
							// subtree doesn't contain any nested source folders
							IPath destPath = destination.append(path
									.removeFirstSegments(sourceSegmentCount));
							IResource destRes;
							if ((updateModelFlags & IProjectFragment.REPLACE) != 0
									&& (destRes = workspaceRoot
											.findMember(destPath)) != null) {
								destRes.delete(updateResourceFlags,
										progressMonitor);
							}
							proxy.requestResource().copy(destPath,
									updateResourceFlags, progressMonitor);
							return false;
						}
					} else {
						IPath path = proxy.requestFullPath();
						IPath destPath = destination.append(path
								.removeFirstSegments(sourceSegmentCount));
						IResource destRes;
						if ((updateModelFlags & IProjectFragment.REPLACE) != 0
								&& (destRes = workspaceRoot
										.findMember(destPath)) != null) {
							destRes
									.delete(updateResourceFlags,
											progressMonitor);
						}
						proxy.requestResource().copy(destPath,
								updateResourceFlags, progressMonitor);
						return false;
					}
				}
			};
			try {
				rootResource.accept(visitor, IResource.NONE);
			} catch (CoreException e) {
				throw new ModelException(e);
			}
		}
		this.setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
	}

	protected void addEntryToBuildpath(IBuildpathEntry rootEntry,
			IWorkspaceRoot workspaceRoot) throws ModelException {

		IProject destProject = workspaceRoot.getProject(this.destination
				.segment(0));
		IScriptProject jProject = DLTKCore.create(destProject);
		IBuildpathEntry[] buildpath = jProject.getRawBuildpath();
		int length = buildpath.length;
		IBuildpathEntry[] newBuildpath;

		// case of existing entry and REPLACE was specified
		if ((this.updateModelFlags & IProjectFragment.REPLACE) != 0) {
			// find existing entry
			for (int i = 0; i < length; i++) {
				if (this.destination.equals(buildpath[i].getPath())) {
					newBuildpath = new IBuildpathEntry[length];
					System.arraycopy(buildpath, 0, newBuildpath, 0, length);
					newBuildpath[i] = copy(rootEntry);
					jProject.setRawBuildpath(newBuildpath, progressMonitor);
					return;
				}
			}
		}

		// other cases
		int position;
		if (this.sibling == null) {
			// insert at the end
			position = length;
		} else {
			// insert before sibling
			position = -1;
			for (int i = 0; i < length; i++) {
				if (this.sibling.equals(buildpath[i])) {
					position = i;
					break;
				}
			}
		}
		if (position == -1) {
			throw new ModelException(new ModelStatus(
					IModelStatusConstants.INVALID_SIBLING, this.sibling
							.toString()));
		}
		newBuildpath = new IBuildpathEntry[length + 1];
		if (position != 0) {
			System.arraycopy(buildpath, 0, newBuildpath, 0, position);
		}
		if (position != length) {
			System.arraycopy(buildpath, position, newBuildpath, position + 1,
					length - position);
		}
		IBuildpathEntry newEntry = copy(rootEntry);
		newBuildpath[position] = newEntry;
		jProject.setRawBuildpath(newBuildpath, progressMonitor);
	}

	/*
	 * Copies the given buildpath entry replacing its path with the destination
	 * path if it is a source folder or a library.
	 */
	protected IBuildpathEntry copy(IBuildpathEntry entry) throws ModelException {
		switch (entry.getEntryKind()) {
		case IBuildpathEntry.BPE_CONTAINER:
			return DLTKCore.newContainerEntry(entry.getPath(), entry
					.getAccessRules(), entry.getExtraAttributes(), entry
					.isExported());
		case IBuildpathEntry.BPE_LIBRARY:
			try {
				return DLTKCore.newLibraryEntry(this.destination, entry
						.getAccessRules(), entry.getExtraAttributes(), entry
						.isExported(), entry.isExternal());
			} catch (AssertionFailedException e) {
				IModelStatus status = new ModelStatus(
						IModelStatusConstants.INVALID_PATH, e.getMessage());
				throw new ModelException(status);
			}
		case IBuildpathEntry.BPE_PROJECT:
			return DLTKCore.newProjectEntry(entry.getPath(), entry
					.getAccessRules(), entry.combineAccessRules(), entry
					.getExtraAttributes(), entry.isExported());
		case IBuildpathEntry.BPE_SOURCE:
			return DLTKCore.newSourceEntry(this.destination, entry
					.getInclusionPatterns(), entry.getExclusionPatterns(),
					entry.getExtraAttributes());
		default:
			throw new ModelException(new ModelStatus(
					IModelStatusConstants.ELEMENT_DOES_NOT_EXIST, this
							.getElementToProcess()));
		}
	}

	@Override
	public IModelStatus verify() {
		IModelStatus status = super.verify();
		if (!status.isOK()) {
			return status;
		}
		IProjectFragment root = (IProjectFragment) 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);
			}
		}

		if ((this.updateModelFlags & IProjectFragment.DESTINATION_PROJECT_BUILDPATH) != 0) {
			String destProjectName = this.destination.segment(0);
			IProject project = ResourcesPlugin.getWorkspace().getRoot()
					.getProject(destProjectName);
			if (DLTKLanguageManager.hasScriptNature(project)) {
				try {
					IScriptProject destProject = DLTKCore.create(project);
					IBuildpathEntry[] destBuildpath = destProject
							.getRawBuildpath();
					boolean foundSibling = false;
					boolean foundExistingEntry = false;
					for (int i = 0, length = destBuildpath.length; i < length; i++) {
						IBuildpathEntry entry = destBuildpath[i];
						if (entry.equals(this.sibling)) {
							foundSibling = true;
							break;
						}
						if (entry.getPath().equals(this.destination)) {
							foundExistingEntry = true;
						}
					}
					if (this.sibling != null && !foundSibling) {
						return new ModelStatus(
								IModelStatusConstants.INVALID_SIBLING,
								this.sibling.toString());
					}
					if (foundExistingEntry
							&& (this.updateModelFlags & IProjectFragment.REPLACE) == 0) {
						return new ModelStatus(
								IModelStatusConstants.NAME_COLLISION, Messages
										.bind(Messages.status_nameCollision,
												new String[] { this.destination
														.toString() }));
					}
				} catch (ModelException e) {
					return e.getModelStatus();
				}
			}
		}

		return ModelStatus.VERIFIED_OK;
	}
}
