/*******************************************************************************
 * 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
	 */
	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
	 */
	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);
	}
}
