/*******************************************************************************
 * Copyright (c) 2012, 2017 Obeo 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
 * 
 * Contributors:
 *     Obeo - initial API and implementation
 *     Alexandra Buzila - Bug 457117
 *     Philip Langer - bug 457839, 516489
 *     Michael Borkowski - Bug 462863
 *******************************************************************************/
package org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.text;

import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableSet;
import com.google.common.eventbus.Subscribe;
import com.google.common.io.ByteStreams;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.EventObject;
import java.util.ResourceBundle;
import java.util.Set;

import org.eclipse.compare.CompareNavigator;
import org.eclipse.compare.ICompareNavigator;
import org.eclipse.compare.IStreamContentAccessor;
import org.eclipse.compare.contentmergeviewer.IMergeViewerContentProvider;
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
import org.eclipse.compare.internal.CompareHandlerService;
import org.eclipse.compare.internal.MergeSourceViewer;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.Conflict;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceState;
import org.eclipse.emf.compare.command.ICompareCommandStack;
import org.eclipse.emf.compare.command.ICompareCopyCommand;
import org.eclipse.emf.compare.domain.ICompareEditingDomain;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
import org.eclipse.emf.compare.ide.ui.internal.configuration.EMFCompareConfiguration;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.EMFCompareContentMergeViewerResourceBundle;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.RedoAction;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.UndoAction;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.CompareInputAdapter;
import org.eclipse.emf.compare.ide.ui.mergeresolution.MergeResolutionManager;
import org.eclipse.emf.compare.internal.utils.ComparisonUtil;
import org.eclipse.emf.compare.rcp.ui.internal.configuration.ICompareEditingDomainChange;
import org.eclipse.emf.compare.rcp.ui.internal.contentmergeviewer.IModelUpdateStrategy;
import org.eclipse.emf.compare.rcp.ui.internal.util.SWTUtil;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewer.MergeViewerSide;
import org.eclipse.emf.compare.utils.IEqualityHelper;
import org.eclipse.emf.edit.command.ChangeCommand;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.actions.ActionFactory;

/**
 * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
 */
public class EMFCompareTextMergeViewer extends TextMergeViewer implements CommandStackListener {

	private static final String BUNDLE_NAME = EMFCompareTextMergeViewer.class.getName();

	private DynamicObject fDynamicObject;

	private UndoAction fUndoAction;

	private RedoAction fRedoAction;

	private MergeResolutionManager mergeResolutionManager;

	/**
	 * @param parent
	 * @param configuration
	 */
	public EMFCompareTextMergeViewer(Composite parent, EMFCompareConfiguration configuration) {
		super(parent, configuration);
		setContentProvider(new EMFCompareTextMergeViewerContentProvider(configuration));

		editingDomainChange(null, configuration.getEditingDomain());

		configuration.getEventBus().register(this);

		mergeResolutionManager = new MergeResolutionManager(
				EMFCompareIDEUIPlugin.getDefault().getMergeResolutionListenerRegistry());
	}

	/**
	 * @param oldValue
	 * @param newValue
	 */
	@Subscribe
	public void editingDomainChange(ICompareEditingDomainChange event) {
		ICompareEditingDomain oldValue = event.getOldValue();
		ICompareEditingDomain newValue = event.getNewValue();
		editingDomainChange(oldValue, newValue);
	}

	public void editingDomainChange(ICompareEditingDomain oldValue, ICompareEditingDomain newValue) {
		if (oldValue != null) {
			ICompareCommandStack commandStack = oldValue.getCommandStack();
			commandStack.removeCommandStackListener(this);
		}
		if (newValue != oldValue) {
			if (newValue != null) {
				ICompareCommandStack commandStack = newValue.getCommandStack();
				commandStack.addCommandStackListener(this);
				setLeftDirty(commandStack.isLeftSaveNeeded());
				setRightDirty(commandStack.isRightSaveNeeded());
			}
			if (fUndoAction != null) {
				fUndoAction.setEditingDomain(newValue);
			}
			if (fRedoAction != null) {
				fRedoAction.setEditingDomain(newValue);
			}
		}
	}

	public void commandStackChanged(EventObject event) {
		if (fUndoAction != null) {
			fUndoAction.update();
		}
		if (fRedoAction != null) {
			fRedoAction.update();
		}
		if (getCompareConfiguration().getEditingDomain() != null) {
			ICompareCommandStack commandStack = getCompareConfiguration().getEditingDomain()
					.getCommandStack();
			setLeftDirty(commandStack.isLeftSaveNeeded());
			setRightDirty(commandStack.isRightSaveNeeded());
		}

		IMergeViewerContentProvider contentProvider = (IMergeViewerContentProvider)getContentProvider();

		final String leftValueFromModel = getString(
				(IStreamContentAccessor)contentProvider.getLeftContent(getInput()));
		final String rightValueFromModel = getString(
				(IStreamContentAccessor)contentProvider.getRightContent(getInput()));

		SWTUtil.safeAsyncExec(new Runnable() {
			public void run() {
				String leftValueFromWidget = getContents(true, Charsets.UTF_8.name());
				String rightValueFromWidget = getContents(false, Charsets.UTF_8.name());
				IEqualityHelper equalityHelper = getCompareConfiguration().getComparison()
						.getEqualityHelper();
				if (!equalityHelper.matchingAttributeValues(leftValueFromModel, leftValueFromWidget)
						|| !equalityHelper.matchingAttributeValues(rightValueFromModel,
								rightValueFromWidget)) {
					// only refresh if values are different to avoid select-all of the text.
					refresh();
				}
			}
		});
	}

	private String getString(IStreamContentAccessor contentAccessor) {
		String ret = null;
		if (contentAccessor != null) {
			try (InputStream content = contentAccessor.getContents()) {
				ret = new String(ByteStreams.toByteArray(content), Charsets.UTF_8.name());
			} catch (CoreException | IOException e) {
				// Empty on purpose
			}
		}
		return ret;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#getCompareConfiguration()
	 */
	@Override
	protected EMFCompareConfiguration getCompareConfiguration() {
		return (EMFCompareConfiguration)super.getCompareConfiguration();
	}

	/**
	 * Inhibits this method to avoid asking to save on each input change!!
	 * 
	 * @see org.eclipse.compare.contentmergeviewer.ContentMergeViewer#doSave(java.lang.Object,
	 *      java.lang.Object)
	 */
	@Override
	protected boolean doSave(Object newInput, Object oldInput) {
		return false;
	}

	protected String getContents(boolean isLeft, String charsetName) {
		try {
			return new String(getContents(isLeft), charsetName);
		} catch (UnsupportedEncodingException e) {
			// UTF_8 is a standard charset guaranteed to be supported by all Java platform
			// implementations
		}
		return null; // can not happen.
	}

	/**
	 * @return the fDynamicObject
	 */
	public DynamicObject getDynamicObject() {
		if (fDynamicObject == null) {
			this.fDynamicObject = new DynamicObject(this);
		}
		return fDynamicObject;
	}

	@SuppressWarnings("restriction")
	protected final MergeSourceViewer getAncestorSourceViewer() {
		return (MergeSourceViewer)getDynamicObject().get("fAncestor"); //$NON-NLS-1$
	}

	@SuppressWarnings("restriction")
	protected final MergeSourceViewer getLeftSourceViewer() {
		return (MergeSourceViewer)getDynamicObject().get("fLeft"); //$NON-NLS-1$
	}

	@SuppressWarnings("restriction")
	protected final MergeSourceViewer getRightSourceViewer() {
		return (MergeSourceViewer)getDynamicObject().get("fRight"); //$NON-NLS-1$
	}

	@SuppressWarnings("restriction")
	protected final CompareHandlerService getHandlerService() {
		return (CompareHandlerService)getDynamicObject().get("fHandlerService"); //$NON-NLS-1$
	}

	protected final void setHandlerService(@SuppressWarnings("restriction") CompareHandlerService service) {
		getDynamicObject().set("fHandlerService", service); //$NON-NLS-1$
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.compare.contentmergeviewer.TextMergeViewer#createControls(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected void createControls(Composite composite) {
		super.createControls(composite);
		attachListeners(getAncestorSourceViewer(), MergeViewerSide.ANCESTOR);
		attachListeners(getLeftSourceViewer(), MergeViewerSide.LEFT);
		attachListeners(getRightSourceViewer(), MergeViewerSide.RIGHT);
	}

	protected void attachListeners(MergeSourceViewer viewer, final MergeViewerSide side) {
		// Nothing to do on the ancestor pane, which should not be edited
		if (viewer != null && (side == MergeViewerSide.LEFT || side == MergeViewerSide.RIGHT)) {
			final StyledText textWidget = viewer.getSourceViewer().getTextWidget();
			textWidget.addFocusListener(new FocusListener() {
				public void focusLost(FocusEvent e) {
					getHandlerService().setGlobalActionHandler(ActionFactory.UNDO.getId(), null);
					getHandlerService().setGlobalActionHandler(ActionFactory.REDO.getId(), null);
				}

				public void focusGained(FocusEvent e) {
					getHandlerService().setGlobalActionHandler(ActionFactory.UNDO.getId(), fUndoAction);
					getHandlerService().setGlobalActionHandler(ActionFactory.REDO.getId(), fRedoAction);
				}
			});
			viewer.getSourceViewer().addTextListener(new ITextListener() {
				public void textChanged(TextEvent event) {
					final Object oldInput = getInput();
					if (event.getDocumentEvent() != null && isCompareInputAdapterHoldingDiff(oldInput)) {
						final CompareInputAdapter inputAdapter = (CompareInputAdapter)oldInput;
						final IModelUpdateStrategy modelUpdateStrategy = inputAdapter
								.getModelUpdateStrategy();
						final Diff diff = (Diff)inputAdapter.getComparisonObject();
						updateModel(diff, modelUpdateStrategy, MergeViewerSide.LEFT);
						updateModel(diff, modelUpdateStrategy, MergeViewerSide.RIGHT);
					}
				}
			});
		}
	}

	/**
	 * Specifies whether the given {@code input} is a {@link CompareInputAdapter} that holds a {@link Diff}.
	 * 
	 * @param input
	 *            Object to check.
	 * @return <code>true</code> if {@code input} is a {@link CompareInputAdapter} holding a a {@link Diff}.
	 */
	private boolean isCompareInputAdapterHoldingDiff(Object input) {
		return input instanceof CompareInputAdapter
				&& ((CompareInputAdapter)input).getComparisonObject() != null
				&& ((CompareInputAdapter)input).getComparisonObject() instanceof Diff;
	}

	/**
	 * Updates the underlying model with the given {@code modelUpdateStrategy} on the given {@code side} in
	 * the context of the given {@code diff}.
	 * 
	 * @param diff
	 *            The context of the model update.
	 * @param modelUpdateStrategy
	 *            The model update strategy to be used.
	 * @param side
	 *            The side on which to perform the udpate.
	 */
	private void updateModel(Diff diff, IModelUpdateStrategy modelUpdateStrategy, MergeViewerSide side) {
		if (isEditable(side) && modelUpdateStrategy.canUpdate(diff, side)) {
			final String newValue = getCurrentValueFromViewer(side);
			final Command updateCmd = modelUpdateStrategy.getModelUpdateCommand(diff, newValue, side);
			final RejectAffectedDiffCommand rejectDiffsCmd = new RejectAffectedDiffCommand(diff);
			final CompoundCommand compoundCmd = createCompoundCompareCommand(side, updateCmd, rejectDiffsCmd);
			getCompareConfiguration().getEditingDomain().getCommandStack().execute(compoundCmd);
		}
	}

	/**
	 * Specifies whether the content merge viewers on the given {@code side} are editable.
	 * 
	 * @param side
	 *            The side to check.
	 * @return <code>true</code> if the content merge viewer is editable on {@code side}, <code>false</code>
	 *         otherwise.
	 */
	private boolean isEditable(MergeViewerSide side) {
		final boolean isLeft = MergeViewerSide.LEFT.equals(side);
		return getCompareConfiguration().isEditable(isLeft);
	}

	/**
	 * Returns the current value from the viewer on the given {@code side}.
	 * 
	 * @param side
	 *            The side to get the value for.
	 * @return The content of the viewer on the given {@code side}.
	 */
	private String getCurrentValueFromViewer(MergeViewerSide side) {
		final boolean isLeft = MergeViewerSide.LEFT.equals(side);
		final GetContentRunnable runnable = new GetContentRunnable(isLeft);
		Display.getDefault().syncExec(runnable);
		return (String)runnable.getResult();
	}

	/**
	 * Creates a compound compare command for the given {@code side} and the given {@code commands}.
	 * 
	 * @param side
	 *            The side on which the compare command is to be executed.
	 * @param commands
	 *            The commands to be enclosed in the compound command.
	 * @return The compound compare command.
	 */
	private CompoundCompareCommand createCompoundCompareCommand(MergeViewerSide side, Command... commands) {
		final CompoundCompareCommand compoundCommand = new CompoundCompareCommand(side);
		for (Command command : commands) {
			compoundCommand.append(command);
		}
		return compoundCommand;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.compare.contentmergeviewer.TextMergeViewer#createToolItems(org.eclipse.jface.action.ToolBarManager)
	 */
	@SuppressWarnings("restriction")
	@Override
	protected void createToolItems(ToolBarManager toolBarManager) {
		super.createToolItems(toolBarManager);

		fRedoAction = new RedoAction(getCompareConfiguration().getEditingDomain());
		fUndoAction = new UndoAction(getCompareConfiguration().getEditingDomain());

		getHandlerService().setGlobalActionHandler(ActionFactory.UNDO.getId(), fUndoAction);
		getHandlerService().setGlobalActionHandler(ActionFactory.REDO.getId(), fRedoAction);
	}

	/**
	 * Called by the framework when the last (or first) diff of the current content viewer has been reached.
	 * This will open the content viewer for the next (or previous) diff displayed in the structure viewer.
	 * 
	 * @param next
	 *            <code>true</code> if we are to open the next structure viewer's diff, <code>false</code> if
	 *            we should go to the previous instead.
	 */
	protected void endOfContentReached(boolean next) {
		final Control control = getControl();
		if (control != null && !control.isDisposed()) {
			final ICompareNavigator navigator = getCompareConfiguration().getContainer().getNavigator();
			if (navigator instanceof CompareNavigator && ((CompareNavigator)navigator).hasChange(next)) {
				navigator.selectChange(next);
			}
		}
	}

	/**
	 * Called by the framework to navigate to the next (or previous) difference. This will open the content
	 * viewer for the next (or previous) diff displayed in the structure viewer.
	 * 
	 * @param next
	 *            <code>true</code> if we are to open the next structure viewer's diff, <code>false</code> if
	 *            we should go to the previous instead.
	 */
	protected void navigate(boolean next) {
		final Control control = getControl();
		if (control != null && !control.isDisposed()) {
			final ICompareNavigator navigator = getCompareConfiguration().getContainer().getNavigator();
			if (navigator instanceof CompareNavigator && ((CompareNavigator)navigator).hasChange(next)) {
				navigator.selectChange(next);
			}
		}
	}

	@Override
	protected ResourceBundle getResourceBundle() {
		return new EMFCompareContentMergeViewerResourceBundle(ResourceBundle.getBundle(BUNDLE_NAME));
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.compare.contentmergeviewer.TextMergeViewer#handleDispose(org.eclipse.swt.events.DisposeEvent)
	 */
	@Override
	protected void handleDispose(DisposeEvent event) {
		getCompareConfiguration().getEventBus().unregister(this);

		editingDomainChange(getCompareConfiguration().getEditingDomain(), null);

		fRedoAction = null;
		fUndoAction = null;

		// Remove all references to the inputs (avoid short-term leak of the resource sets retained via
		// references to org.eclipse.compare.contentmergeviewer.TextMergeViewer$ContributorInfo.)
		updateContent(null, null, null);

		super.handleDispose(event);
	}

	/**
	 * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
	 */
	private final class GetContentRunnable implements Runnable {
		/**
		 * 
		 */
		private final boolean isLeft;

		private String result;

		/**
		 * @param isLeft
		 */
		private GetContentRunnable(boolean isLeft) {
			this.isLeft = isLeft;
		}

		public void run() {
			result = getContents(isLeft, Charsets.UTF_8.name());
		}

		public Object getResult() {
			return result;
		}
	}

	/**
	 * Command to directly modify the semantic model and reject the related difference.
	 * 
	 * @author cnotot
	 */
	private static class RejectAffectedDiffCommand extends ChangeCommand {

		private Diff difference;

		public RejectAffectedDiffCommand(Diff difference) {
			super(ImmutableSet.<Notifier> builder().addAll(getAffectedDiff(difference)).build());
			this.difference = difference;
		}

		@Override
		public void doExecute() {
			for (Diff affectedDiff : getAffectedDiff(difference)) {
				affectedDiff.setState(DifferenceState.DISCARDED);
			}
		}

		private static Set<Diff> getAffectedDiff(Diff diff) {
			EList<Conflict> conflicts = ComparisonUtil.getComparison(diff).getConflicts();
			for (Conflict conflict : conflicts) {
				EList<Diff> conflictualDifferences = conflict.getDifferences();
				if (conflictualDifferences.contains(diff)) {
					return ImmutableSet.copyOf(conflictualDifferences);
				}
			}
			return ImmutableSet.of(diff);
		}
	}

	/**
	 * A compound command that also implements the {@link ICompareCopyCommand} to be executable in the context
	 * of a comparison.
	 * 
	 * @author Philip Langer <planger@eclipsesource.com>
	 */
	private static class CompoundCompareCommand extends CompoundCommand implements ICompareCopyCommand {

		/** The side on which this command executes. */
		private MergeViewerSide side;

		/**
		 * Creates a new compound command for the given {@code side}.
		 * 
		 * @param side
		 *            The side on which this command executes.
		 */
		public CompoundCompareCommand(MergeViewerSide side) {
			this.side = side;
		}

		/**
		 * {@inheritDoc}
		 */
		public boolean isLeftToRight() {
			return !MergeViewerSide.LEFT.equals(side);
		}
	}

	@Override
	protected void flushContent(Object oldInput, IProgressMonitor monitor) {
		super.flushContent(oldInput, monitor);
		mergeResolutionManager.handleFlush(oldInput);
	}
}
