/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.core.mapping.provider;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceRuleFactory;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.MultiRule;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.core.mapping.DelegatingStorageMerger;
import org.eclipse.team.core.mapping.IMergeContext;
import org.eclipse.team.core.mapping.IMergeStatus;
import org.eclipse.team.core.mapping.IResourceDiff;
import org.eclipse.team.core.mapping.IResourceDiffTree;
import org.eclipse.team.core.mapping.IResourceMappingMerger;
import org.eclipse.team.core.mapping.IStorageMerger;
import org.eclipse.team.core.mapping.ISynchronizationScopeManager;
import org.eclipse.team.internal.core.Messages;
import org.eclipse.team.internal.core.Policy;
import org.eclipse.team.internal.core.TeamPlugin;
import org.eclipse.team.internal.core.mapping.SyncInfoToDiffConverter;

/**
 * Provides the context for an <code>IResourceMappingMerger</code>.
 * It provides access to the ancestor and remote resource mapping contexts
 * so that resource mapping mergers can attempt head-less auto-merges.
 * The ancestor context is only required for merges while the remote
 * is required for both merge and replace.
 *
 * @see IResourceMappingMerger
 * @since 3.2
 */
public abstract class MergeContext extends SynchronizationContext implements IMergeContext {

	/**
	 * Create a merge context.
	 *
	 * @param manager   the manager that defines the scope of the synchronization
	 * @param type      the type of synchronization (ONE_WAY or TWO_WAY)
	 * @param deltaTree the sync info tree that contains all out-of-sync resources
	 */
	protected MergeContext(ISynchronizationScopeManager manager, int type, IResourceDiffTree deltaTree) {
		super(manager, type, deltaTree);
	}

	@Override
	public void reject(final IDiff[] diffs, IProgressMonitor monitor) throws CoreException {
		run(monitor1 -> {
			for (IDiff node : diffs) {
				reject(node, monitor1);
			}
		}, getMergeRule(diffs), IResource.NONE, monitor);
	}

	@Override
	public void markAsMerged(final IDiff[] nodes, final boolean inSyncHint, IProgressMonitor monitor) throws CoreException {
		run(monitor1 -> {
			for (IDiff node : nodes) {
				markAsMerged(node, inSyncHint, monitor1);
			}
		}, getMergeRule(nodes), IResource.NONE, monitor);
	}

	@Override
	public IStatus merge(final IDiff[] deltas, final boolean force, IProgressMonitor monitor) throws CoreException {
		final List<IFile> failedFiles = new ArrayList<>();
		run(monitor1 -> {
			try {
				monitor1.beginTask(null, deltas.length * 100);
				for (IDiff delta : deltas) {
					IStatus s = merge(delta, force, Policy.subMonitorFor(monitor1, 100));
					if (!s.isOK()) {
						if (s.getCode() == IMergeStatus.CONFLICTS) {
							failedFiles.addAll(Arrays.asList(((IMergeStatus)s).getConflictingFiles()));
						} else {
							throw new CoreException(s);
						}
					}
				}
			} finally {
				monitor1.done();
			}
		}, getMergeRule(deltas), IWorkspace.AVOID_UPDATE, monitor);
		if (failedFiles.isEmpty()) {
			return Status.OK_STATUS;
		} else {
			return new MergeStatus(TeamPlugin.ID, Messages.MergeContext_0, failedFiles.toArray(new IFile[failedFiles.size()]));
		}
	}

	@Override
	public IStatus merge(IDiff diff, boolean ignoreLocalChanges, IProgressMonitor monitor) throws CoreException {
		Policy.checkCanceled(monitor);
		IResource resource = getDiffTree().getResource(diff);
		if (resource.getType() != IResource.FILE) {
			if (diff instanceof IThreeWayDiff) {
				IThreeWayDiff twd = (IThreeWayDiff) diff;
				if ((ignoreLocalChanges || getMergeType() == TWO_WAY)
						&& resource.getType() == IResource.FOLDER
						&& twd.getKind() == IDiff.ADD
						&& twd.getDirection() == IThreeWayDiff.OUTGOING
						&& ((IFolder)resource).members().length == 0) {
					// Delete the local folder addition
					((IFolder)resource).delete(false, monitor);
				} else if (resource.getType() == IResource.FOLDER
						&& !resource.exists()
						&& twd.getKind() == IDiff.ADD
						&& twd.getDirection() == IThreeWayDiff.INCOMING) {
					ensureParentsExist(resource, monitor);
					((IFolder)resource).create(false, true, monitor);
					makeInSync(diff, monitor);
				}
			}
			return Status.OK_STATUS;
		}
		if (diff instanceof IThreeWayDiff && !ignoreLocalChanges && getMergeType() == THREE_WAY) {
			IThreeWayDiff twDelta = (IThreeWayDiff) diff;
			int direction = twDelta.getDirection();
			if (direction == IThreeWayDiff.OUTGOING) {
				// There's nothing to do so return OK
				return Status.OK_STATUS;
			}
			if (direction == IThreeWayDiff.INCOMING) {
				// Just copy the stream since there are no conflicts
				performReplace(diff, monitor);
				return Status.OK_STATUS;
			}
			// direction == SyncInfo.CONFLICTING
			int type = twDelta.getKind();
			if (type == IDiff.REMOVE) {
				makeInSync(diff, monitor);
				return Status.OK_STATUS;
			}
			// type == SyncInfo.CHANGE
			IResourceDiff remoteChange = (IResourceDiff)twDelta.getRemoteChange();
			IFileRevision remote = null;
			if (remoteChange != null) {
				remote = remoteChange.getAfterState();
			}
			if (remote == null || !getLocalFile(diff).exists()) {
				// Nothing we can do so return a conflict status
				// TODO: Should we handle the case where the local and remote have the same contents for a conflicting addition?
				return new MergeStatus(TeamPlugin.ID, NLS.bind(Messages.MergeContext_1, new String[] { diff.getPath().toString() }), new IFile[] { getLocalFile(diff) });
			}
			// We have a conflict, a local, base and remote so we can do
			// a three-way merge
			return performThreeWayMerge(twDelta, monitor);
		} else {
			performReplace(diff, monitor);
			return Status.OK_STATUS;
		}

	}

	/**
	 * Perform a three-way merge on the given three-way diff that contains a content conflict.
	 * By default, this method makes use of {@link IStorageMerger} instances registered
	 * with the <code>storageMergers</code> extension point. Note that the ancestor
	 * of the given diff may be missing. Some {@link IStorageMerger} instances
	 * can still merge without an ancestor so we need to consult the
	 * appropriate merger to find out.
	 * @param diff the diff
	 * @param monitor a progress monitor
	 * @return a status indicating the results of the merge
	 */
	protected IStatus performThreeWayMerge(final IThreeWayDiff diff, IProgressMonitor monitor) throws CoreException {
		final IStatus[] result = new IStatus[] { Status.OK_STATUS };
		run(monitor1 -> {
			monitor1.beginTask(null, 100);
			IResourceDiff localDiff = (IResourceDiff)diff.getLocalChange();
			IResourceDiff remoteDiff = (IResourceDiff)diff.getRemoteChange();
			IStorageMerger merger = getAdapter(IStorageMerger.class);
			if (merger == null)
				merger = DelegatingStorageMerger.getInstance();
			IFile file = (IFile)localDiff.getResource();
			monitor1.subTask(NLS.bind(Messages.MergeContext_5, file.getFullPath().toString()));
			String osEncoding = file.getCharset();
			IFileRevision ancestorState = localDiff.getBeforeState();
			IFileRevision remoteState = remoteDiff.getAfterState();
			IStorage ancestorStorage;
			if (ancestorState != null)
				ancestorStorage = ancestorState.getStorage(Policy.subMonitorFor(monitor1, 30));
			else
				ancestorStorage = null;
			IStorage remoteStorage = remoteState.getStorage(Policy.subMonitorFor(monitor1, 30));
			OutputStream os = getTempOutputStream(file);
			try {
				IStatus status = merger.merge(os, osEncoding, ancestorStorage, file, remoteStorage, Policy.subMonitorFor(monitor1, 30));
				if (status.isOK()) {
					file.setContents(getTempInputStream(file, os), false, true, Policy.subMonitorFor(monitor1, 5));
					markAsMerged(diff, false, Policy.subMonitorFor(monitor1, 5));
				} else {
					status = new MergeStatus(status.getPlugin(), status.getMessage(), new IFile[]{file});
				}
				result[0] = status;
			} finally {
				disposeTempOutputStream(file, os);
			}
			monitor1.done();
		}, getMergeRule(diff), IWorkspace.AVOID_UPDATE, monitor);
		return result[0];
	}

	private void disposeTempOutputStream(IFile file, OutputStream output) {
		if (output instanceof ByteArrayOutputStream)
			return;
		// We created a temporary file so we need to clean it up
		try {
			// First make sure the output stream is closed
			// so that file deletion will not fail because of that.
			if (output != null)
				output.close();
		} catch (IOException e) {
			// Ignore
		}
		File tmpFile = getTempFile(file);
		if (tmpFile.exists())
			tmpFile.delete();
	}

	private OutputStream getTempOutputStream(IFile file) throws CoreException {
		File tmpFile = getTempFile(file);
		if (tmpFile.exists())
			tmpFile.delete();
		File parent = tmpFile.getParentFile();
		if (!parent.exists())
			parent.mkdirs();
		try {
			return new BufferedOutputStream(new FileOutputStream(tmpFile));
		} catch (FileNotFoundException e) {
			TeamPlugin.log(IStatus.ERROR, NLS.bind("Could not open temporary file {0} for writing: {1}", new String[] { tmpFile.getAbsolutePath(), e.getMessage() }), e); //$NON-NLS-1$
			return new ByteArrayOutputStream();
		}
	}

	private InputStream getTempInputStream(IFile file, OutputStream output) throws CoreException {
		if (output instanceof ByteArrayOutputStream) {
			ByteArrayOutputStream baos = (ByteArrayOutputStream) output;
			return new ByteArrayInputStream(baos.toByteArray());
		}
		// We created a temporary file so we need to open an input stream on it
		try {
			// First make sure the output stream is closed
			if (output != null)
				output.close();
		} catch (IOException e) {
			// Ignore
		}
		File tmpFile = getTempFile(file);
		try {
			return new BufferedInputStream(new FileInputStream(tmpFile));
		} catch (FileNotFoundException e) {
			throw new CoreException(new Status(IStatus.ERROR, TeamPlugin.ID, IMergeStatus.INTERNAL_ERROR, NLS.bind(Messages.MergeContext_4, new String[] { tmpFile.getAbsolutePath(), e.getMessage() }), e));
		}
	}

	private File getTempFile(IFile file) {
		return TeamPlugin.getPlugin().getStateLocation().append(".tmp").append(file.getName() + ".tmp").toFile(); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private IFile getLocalFile(IDiff delta) {
		return ResourcesPlugin.getWorkspace().getRoot().getFile(delta.getPath());
	}

	/**
	 * Make the local state of the resource associated with the given diff match
	 * that of the remote. This method is invoked by the
	 * {@link #merge(IDiff, boolean, IProgressMonitor)} method. By default, it
	 * either overwrites the local contexts with the remote contents if both
	 * exist, deletes the local if the remote does not exists or adds the local
	 * if the local doesn't exist but the remote does. It then calls
	 * {@link #makeInSync(IDiff, IProgressMonitor)} to give subclasses a change
	 * to make the file associated with the diff in-sync.
	 *
	 * @param diff
	 *            the diff whose local is to be replaced
	 * @param monitor
	 *            a progress monitor
	 * @throws CoreException if an error occurs
	 */
	protected void performReplace(final IDiff diff, IProgressMonitor monitor) throws CoreException {
		IResourceDiff d;
		IFile file = getLocalFile(diff);
		IFileRevision remote = null;
		if (diff instanceof IResourceDiff) {
			d = (IResourceDiff) diff;
			remote = d.getAfterState();
		} else {
			d = (IResourceDiff)((IThreeWayDiff)diff).getRemoteChange();
			if (d != null)
				remote = d.getAfterState();
		}
		if (d == null) {
			d = (IResourceDiff)((IThreeWayDiff)diff).getLocalChange();
			if (d != null)
				remote = d.getBeforeState();
		}

		// Only perform the replace if a local or remote change was found
		if (d != null) {
			performReplace(diff, file, remote, monitor);
		}
	}

	/**
	 * Method that is invoked from
	 * {@link #performReplace(IDiff, IProgressMonitor)} after the local has been
	 * changed to match the remote. Subclasses may override
	 * {@link #performReplace(IDiff, IProgressMonitor)} or this method in order
	 * to properly reconcile the synchronization state. This method is also
	 * invoked from {@link #merge(IDiff, boolean, IProgressMonitor)} if deletion
	 * conflicts are encountered. It can also be invoked from that same method if
	 * a folder is created due to an incoming folder addition.
	 *
	 * @param diff
	 *            the diff whose local is now in-sync
	 * @param monitor
	 *            a progress monitor
	 * @throws CoreException if an error occurs
	 */
	protected abstract void makeInSync(IDiff diff, IProgressMonitor monitor) throws CoreException;

	private void performReplace(final IDiff diff, final IFile file, final IFileRevision remote, IProgressMonitor monitor) throws CoreException {
		run(monitor1 -> {
			try {
				monitor1.beginTask(null, 100);
				monitor1.subTask(NLS.bind(Messages.MergeContext_6, file.getFullPath().toString()));
				if ((remote == null || !remote.exists()) && file.exists()) {
					file.delete(false, true, Policy.subMonitorFor(monitor1, 95));
				} else if (remote != null) {
					ensureParentsExist(file, monitor1);
					InputStream stream = remote.getStorage(monitor1).getContents();
					stream = new BufferedInputStream(stream);
					try {
						if (file.exists()) {
							file.setContents(stream, false, true, Policy.subMonitorFor(monitor1, 95));
						} else {
							file.create(stream, false, Policy.subMonitorFor(monitor1, 95));
						}
					} finally {
						try {
							stream.close();
						} catch (IOException e) {
							// Ignore
						}
					}
				}
				// Performing a replace should leave the file in-sync
				makeInSync(diff, Policy.subMonitorFor(monitor1, 5));
			} finally {
				monitor1.done();
			}
		}, getMergeRule(diff), IWorkspace.AVOID_UPDATE, monitor);
	}

	/**
	 * Ensure that the parent folders of the given resource exist.
	 * This method is invoked from {@link #performReplace(IDiff, IProgressMonitor)}
	 * for files that are being merged that do not exist locally.
	 * By default, this method creates the parents using
	 * {@link IFolder#create(boolean, boolean, IProgressMonitor)}.
	 * Subclasses may override.
	 * @param resource a resource
	 * @param monitor a progress monitor
	 * @throws CoreException if an error occurs
	 */
	protected void ensureParentsExist(IResource resource, IProgressMonitor monitor) throws CoreException {
		IContainer parent = resource.getParent();
		if (parent.getType() != IResource.FOLDER) {
			// this method will only create folders
			return;
		}
		if (!parent.exists()) {
			ensureParentsExist(parent, monitor);
			((IFolder)parent).create(false, true, monitor);
		}
	}

	/**
	 * Default implementation of <code>run</code> that invokes the
	 * corresponding <code>run</code> on {@link org.eclipse.core.resources.IWorkspace}.
	 * @see org.eclipse.team.core.mapping.IMergeContext#run(org.eclipse.core.resources.IWorkspaceRunnable, org.eclipse.core.runtime.jobs.ISchedulingRule, int, org.eclipse.core.runtime.IProgressMonitor)
	 */
	@Override
	public void run(IWorkspaceRunnable runnable, ISchedulingRule rule, int flags, IProgressMonitor monitor) throws CoreException {
		ResourcesPlugin.getWorkspace().run(runnable, rule, flags, monitor);
	}

	/**
	 * Default implementation that returns the resource itself if it exists
	 * and the first existing parent if the resource does not exist.
	 * Subclass should override to provide the appropriate rule.
	 * @see org.eclipse.team.core.mapping.IMergeContext#getMergeRule(IDiff)
	 */
	@Override
	public ISchedulingRule getMergeRule(IDiff diff) {
		IResource resource = getDiffTree().getResource(diff);
		IResourceRuleFactory ruleFactory = ResourcesPlugin.getWorkspace().getRuleFactory();
		ISchedulingRule rule;
		if (!resource.exists()) {
			// for additions return rule for all parents that need to be created
			IContainer parent = resource.getParent();
			while (!parent.exists()) {
				resource = parent;
				parent = parent.getParent();
			}
			rule = ruleFactory.createRule(resource);
		} else if (SyncInfoToDiffConverter.getRemote(diff) == null){
			rule = ruleFactory.deleteRule(resource);
		} else {
			rule = ruleFactory.modifyRule(resource);
		}
		return rule;
	}

	@Override
	public ISchedulingRule getMergeRule(IDiff[] deltas) {
		ISchedulingRule result = null;
		for (IDiff node : deltas) {
			ISchedulingRule rule = getMergeRule(node);
			if (result == null) {
				result = rule;
			} else {
				result = MultiRule.combine(result, rule);
			}
		}
		return result;
	}

	@Override
	public int getMergeType() {
		return getType();
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> T getAdapter(Class<T> adapter) {
		if (adapter == IStorageMerger.class) {
			return (T) DelegatingStorageMerger.getInstance();
		}
		return super.getAdapter(adapter);
	}
}
