/*****************************************************************************
 * Copyright (c) 2013, 2017 CEA LIST and others.
 *
 * All rights reserved. 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:
 *   CEA LIST - Initial API and implementation
 *   Eike Stepper (CEA) - bug 466520
 *****************************************************************************/
package org.eclipse.papyrus.cdo.internal.ui.editors;

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

import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch;
import org.eclipse.emf.cdo.dawn.gmf.util.DawnDiagramUpdater;
import org.eclipse.emf.cdo.dawn.spi.DawnState;
import org.eclipse.emf.cdo.transaction.CDOTransactionConflictEvent;
import org.eclipse.emf.cdo.transaction.CDOTransactionFinishedEvent;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.view.CDOViewInvalidationEvent;
import org.eclipse.emf.cdo.view.CDOViewLocksChangedEvent;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.BasicNotifierImpl.EObservableAdapterList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.workspace.IWorkspaceCommandStack;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.papyrus.cdo.core.resource.CDOUndoContext;
import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
import org.eclipse.papyrus.cdo.internal.ui.Activator;
import org.eclipse.papyrus.cdo.internal.ui.decorators.CDOStateAdapter;
import org.eclipse.papyrus.cdo.internal.ui.decorators.CDOStateLabelDecorator;
import org.eclipse.papyrus.cdo.internal.ui.l10n.Messages;
import org.eclipse.papyrus.cdo.internal.ui.util.UIUtil;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
import org.eclipse.papyrus.infra.widgets.toolbox.notification.Type;
import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.NotificationBuilder;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * This is the PapyrusTransactionListener type. Enjoy.
 */
public class PapyrusTransactionListener implements IListener {

	private final ServicesRegistry services;

	private final Predicate<Adapter> shouldPropagate = new Predicate<Adapter>() {

		@Override
		public boolean apply(Adapter input) {
			return (input instanceof ECrossReferenceAdapter) //
					|| (input instanceof EContentAdapter) //
					|| (input instanceof ChangeRecorder);
		}
	};

	private final Set<Adapter> contentAdapters;

	public PapyrusTransactionListener(ServicesRegistry services, ResourceSet resourceSet) {
		super();

		this.services = services;

		contentAdapters = Sets.newHashSet(Iterables.filter(resourceSet.eAdapters(), shouldPropagate));
		((EObservableAdapterList) resourceSet.eAdapters()).addListener(new EObservableAdapterList.Listener() {

			@Override
			public void added(Notifier notifier, Adapter adapter) {
				if (adapter instanceof EContentAdapter) {
					contentAdapters.add(adapter);
				}
			}

			@Override
			public void removed(Notifier notifier, Adapter adapter) {
				contentAdapters.remove(adapter);
			}
		});

	}

	@Override
	public void notifyEvent(IEvent event) {
		if (event instanceof CDOViewInvalidationEvent) {
			handleViewInvalidationEvent((CDOViewInvalidationEvent) event);
		} else if (event instanceof CDOTransactionConflictEvent) {
			handleTransactionConflictEvent((CDOTransactionConflictEvent) event);
		} else if (event instanceof CDOViewLocksChangedEvent) {
			handleLocksChangedEvent((CDOViewLocksChangedEvent) event);
		} else if (event instanceof CDOTransactionFinishedEvent) {
			handleTransactionFinishedEvent((CDOTransactionFinishedEvent) event);
		} else {
			handleEvent(event);
		}
	}

	protected void handleTransactionConflictEvent(CDOTransactionConflictEvent event) {
		if (UIUtil.ensureUIThread(this, event)) {
			CDOObject cdoObject = event.getConflictingObject();
			EObject element = CDOUtil.getEObject(cdoObject);
			View view = DawnDiagramUpdater.findViewByContainer(element);

			if (view == null) {
				// it's not actually a view that is conflicted, but a model
				// element
				if (cdoObject.cdoConflict()) {
					CDOStateAdapter.setState(element, DawnState.CONFLICT);

					CDOStateLabelDecorator.fireLabelUpdates();
				}
			}
		}
	}

	protected void handleLocksChangedEvent(CDOViewLocksChangedEvent event) {
		if (UIUtil.ensureUIThread(this, event)) {
			Map<EObject, DawnState> changedObjects = new HashMap<EObject, DawnState>();
			CDOView cdoView = event.getSource();

			for (CDOLockState state : event.getLockStates()) {
				Object lockedObject = state.getLockedObject();

				CDOID id;
				if (lockedObject instanceof CDOID) {
					id = (CDOID) lockedObject;
				} else if (lockedObject instanceof CDOIDAndBranch) {
					id = ((CDOIDAndBranch) lockedObject).getID();
				} else {
					throw new RuntimeException("Unexpected object type: " //$NON-NLS-1$
							+ lockedObject);
				}

				if (id != null) {
					CDOObject object = cdoView.getObject(id);
					EObject element = CDOUtil.getEObject(object);

					View view = DawnDiagramUpdater.findViewByContainer(element);

					if (view == null) {
						// it's not actually a view that is locked, but a model
						// element
						if (CDOUtils.isLocked(object, true)) {
							changedObjects.put(element, DawnState.LOCKED_REMOTELY);
						} else {
							changedObjects.put(element, DawnState.CLEAN);
						}
					}
				}
			}

			handleLocks(changedObjects);
		}
	}

	/**
	 * @precondition The current thread is the UI thread
	 */
	void handleLocks(Map<EObject, DawnState> changedObjects) {
		if (!changedObjects.isEmpty()) {
			for (Map.Entry<EObject, DawnState> next : changedObjects.entrySet()) {

				EObject element = next.getKey();
				DawnState state = next.getValue();

				CDOStateAdapter.setState(element, state);
			}

			CDOStateLabelDecorator.fireLabelUpdates();
		}
	}

	protected void handleViewInvalidationEvent(CDOViewInvalidationEvent event) {
		if (UIUtil.ensureUIThread(this, event)) {
			// process changed objects to ensure propagation of adapters to new objects.
			// CDO doesn't tell us about new objects, but it does tell us that their
			// containers changed, so we have to go fishing
			for (EObject next : CDOUtils.getEObjects(event.getDirtyObjects())) {
				for (EObject possiblyNew : next.eContents()) {
					synchronizeAdapters(possiblyNew);
				}
			}

			// also, purge any operations from the local history that changed the objects that
			// were changed by the remote transaction
			handleOperationHistory(event);
		}
	}

	protected void synchronizeAdapters(EObject object) {
		object.eAdapters().addAll(Sets.difference(contentAdapters, ImmutableSet.copyOf(object.eAdapters())));
	}

	protected void handleOperationHistory(CDOViewInvalidationEvent event) {
		IOperationHistory history = getOperationHistory();
		if (history != null) {
			Iterable<EObject> affectedObjects = CDOUtils.getEObjects(Iterables.concat(event.getDirtyObjects(), event.getDetachedObjects()));
			if (!Iterables.isEmpty(affectedObjects)) {
				IUndoContext context = new CDOUndoContext(affectedObjects);
				if (context != null) {
					IUndoableOperation undoOperation = history.getUndoOperation(context);
					IUndoableOperation redoOperation = history.getRedoOperation(context);

					if ((undoOperation != null) || (redoOperation != null)) {
						// notify listeners of the impending changes. We do this before flushing
						// the undo context because we depend on the fact that the UndoActionHandler
						// and RedoActionHandler only react when the operation is their current
						// operation (which means it mustn't have the context removed yet) *and* the
						// update is posted asynchronously
						if (undoOperation != null) {
							history.operationChanged(undoOperation);
						}
						if (redoOperation != null) {
							history.operationChanged(redoOperation);
						}

						// flush the history for this editor
						history.dispose(getEditorUndoContext(), true, true, false);

						NotificationBuilder.createAsyncPopup(Messages.PapyrusTransactionListener_0).setType(Type.INFO).run();
					}
				}
			}
		}
	}

	protected IOperationHistory getOperationHistory() {
		IOperationHistory result = null;

		try {
			EditingDomain domain = services.getService(TransactionalEditingDomain.class);
			if (domain != null) {
				CommandStack stack = domain.getCommandStack();
				if (stack instanceof IWorkspaceCommandStack) {
					result = ((IWorkspaceCommandStack) stack).getOperationHistory();
				}
			}
		} catch (ServiceException e) {
			Activator.log.error("Failed to get editor operation history from service registry.", e); //$NON-NLS-1$
		}

		return result;
	}

	protected IUndoContext getEditorUndoContext() {
		IUndoContext result = null;

		try {
			result = services.getService(IUndoContext.class);
		} catch (ServiceException e) {
			Activator.log.error("Failed to get editor undo context from service registry.", e); //$NON-NLS-1$
		}

		return result;
	}

	protected void handleTransactionFinishedEvent(CDOTransactionFinishedEvent event) {
		// review all conflicts and locks
		Map<EObject, DawnState> stateUpdates = Maps.newHashMap();

		for (CDOStateAdapter next : CDOStateAdapter.getAll(event.getSource().getResourceSet())) {

			Object target = next.getTarget();
			if (target instanceof EObject) {
				EObject object = (EObject) target;
				stateUpdates.put(object, CDOUtils.computeState(object));
			}
		}

		for (Map.Entry<EObject, DawnState> next : stateUpdates.entrySet()) {
			CDOStateAdapter.setState(next.getKey(), next.getValue());
		}

		CDOStateLabelDecorator.fireLabelUpdates();
	}

	protected void handleEvent(IEvent event) {
		// pass
	}
}
