/*******************************************************************************
 * Copyright (c) 2004, 2011 Tasktop Technologies 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:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.java.ui;

import java.util.LinkedHashSet;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.ISourceRange;
import org.eclipse.jdt.core.ISourceReference;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.context.core.AbstractContextListener;
import org.eclipse.mylyn.context.core.ContextChangeEvent;
import org.eclipse.mylyn.context.core.ContextCore;
import org.eclipse.mylyn.context.core.IInteractionElement;

/**
 * @author Mik Kersten
 */
public class LandmarkMarkerManager extends AbstractContextListener {

	private static final String ID_MARKER_LANDMARK = "org.eclipse.mylyn.context.ui.markers.landmark"; //$NON-NLS-1$

	private final Map<IInteractionElement, Long> markerMap = new ConcurrentHashMap<IInteractionElement, Long>();

	private final LandmarkUpdateJob updateJob = new LandmarkUpdateJob(
			Messages.LandmarkMarkerManager_Updating_Landmark_Markers);

	public LandmarkMarkerManager() {
		super();
	}

	@Override
	public void contextChanged(ContextChangeEvent event) {
		LinkedHashSet<LandmarkUpdateOperation> runnables = new LinkedHashSet<LandmarkUpdateOperation>();
		switch (event.getEventKind()) {
		case ACTIVATED:
		case DEACTIVATED:
			modelUpdated();
			break;
		case CLEARED:
			if (event.isActiveContext()) {
				modelUpdated();
			}
			break;
		case LANDMARKS_ADDED:
			for (IInteractionElement element : event.getElements()) {
				LandmarkUpdateOperation runnable = createAddLandmarkMarkerOperation(element);
				if (runnable != null) {
					runnables.add(runnable);
				}
			}
			break;
		case ELEMENTS_DELETED:
		case LANDMARKS_REMOVED:
			for (IInteractionElement element : event.getElements()) {
				LandmarkUpdateOperation runnable = createRemoveLandmarkMarkerOperation(element);
				if (runnable != null) {
					runnables.add(runnable);
				}
			}
			break;

		}
		updateJob.updateMarkers(runnables);
	}

	private void modelUpdated() {
		try {
			// remove all known landmark markers
			LinkedHashSet<LandmarkUpdateOperation> runnables = new LinkedHashSet<LandmarkUpdateOperation>();
			for (IInteractionElement node : markerMap.keySet()) {
				LandmarkUpdateOperation runnable = createRemoveLandmarkMarkerOperation(node);
				if (runnable != null) {
					runnables.add(runnable);
				}
			}
			markerMap.clear();
			// add any nodes that are landmarks
			for (IInteractionElement node : ContextCore.getContextManager().getActiveLandmarks()) {
				LandmarkUpdateOperation runnable = createAddLandmarkMarkerOperation(node);
				if (runnable != null) {
					runnables.add(runnable);
				}
			}
			updateJob.updateMarkers(runnables);
		} catch (Throwable t) {
			StatusHandler.log(new Status(IStatus.ERROR, JavaUiBridgePlugin.ID_PLUGIN,
					"Could not update landmark markers", t)); //$NON-NLS-1$
		}
	}

	private LandmarkUpdateOperation createAddLandmarkMarkerOperation(final IInteractionElement node) {
		if (node == null || node.getContentType() == null) {
			return null;
		}
		if (JavaStructureBridge.CONTENT_TYPE.equals(node.getContentType())) {
			final IJavaElement element = JavaCore.create(node.getHandleIdentifier());
			if (!element.exists()) {
				return null;
			}
			if (element instanceof IMember) {
				try {
					final ISourceRange range = ((IMember) element).getNameRange();
					IResource resource = element.getUnderlyingResource();
					if (resource instanceof IFile) {
						LandmarkUpdateOperation runnable = new LandmarkUpdateOperation(resource) {
							public void run(IProgressMonitor monitor) throws CoreException {
								IMarker marker = getResource().createMarker(ID_MARKER_LANDMARK);
								if (marker != null && range != null) {
									marker.setAttribute(IMarker.CHAR_START, range.getOffset());
									marker.setAttribute(IMarker.CHAR_END, range.getOffset() + range.getLength());
									marker.setAttribute(IMarker.MESSAGE, Messages.LandmarkMarkerManager_Mylyn_Landmark);
									marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
									markerMap.put(node, marker.getId());
								}
							}
						};
						return runnable;
					}
				} catch (JavaModelException e) {
					StatusHandler.log(new Status(IStatus.ERROR, JavaUiBridgePlugin.ID_PLUGIN,
							"Could not update marker", e)); //$NON-NLS-1$
				}
			}
		}
		return null;
	}

	private LandmarkUpdateOperation createRemoveLandmarkMarkerOperation(final IInteractionElement node) {
		if (node == null) {
			return null;
		}
		if (JavaStructureBridge.CONTENT_TYPE.equals(node.getContentType())) {
			IJavaElement element = JavaCore.create(node.getHandleIdentifier());
			if (!element.exists()) {
				return null;
			}
			if (element.getAncestor(IJavaElement.COMPILATION_UNIT) != null // stuff
					// from .class files
					&& element instanceof ISourceReference) {
				try {
					IResource resource = element.getUnderlyingResource();
					LandmarkUpdateOperation runnable = new LandmarkUpdateOperation(resource) {
						public void run(IProgressMonitor monitor) throws CoreException {
							if (getResource() != null) {
								try {
									if (markerMap.containsKey(node)) {
										long id = markerMap.get(node);
										IMarker marker = getResource().getMarker(id);
										if (marker != null) {
											marker.delete();
										}
									}
								} catch (NullPointerException e) {
									// FIXME avoid NPE
									StatusHandler.log(new Status(IStatus.ERROR, JavaUiBridgePlugin.ID_PLUGIN,
											"Could not update marker", e)); //$NON-NLS-1$
								}
							}
						}
					};
					return runnable;
				} catch (JavaModelException e) {
					// ignore the Java Model errors
				}
			}
		}
		return null;
	}

	/**
	 * IWorkspaceRunnable that has a reference to the resource that it is operating on
	 */
	private abstract class LandmarkUpdateOperation implements IWorkspaceRunnable {

		private final IResource resource;

		public LandmarkUpdateOperation(IResource resource) {
			Assert.isNotNull(resource);
			this.resource = resource;
		}

		public IResource getResource() {
			return resource;
		}

	}

	/**
	 * Job to handle updating the landmark markers in the background
	 */
	private class LandmarkUpdateJob extends Job {

		private static final int NOT_SCHEDULED = -1;

		private final LinkedHashSet<LandmarkUpdateOperation> queue = new LinkedHashSet<LandmarkUpdateOperation>();

		private long scheduleTime = NOT_SCHEDULED;

		public LandmarkUpdateJob(String name) {
			super(name);
			setSystem(true);
		}

		public synchronized void updateMarkers(LinkedHashSet<LandmarkUpdateOperation> operations) {
			queue.addAll(operations);
			if (queue.size() > 0) {
				if (scheduleTime == NOT_SCHEDULED) {
					scheduleTime = System.currentTimeMillis();
					schedule();
				}
			}
		}

		@Override
		public IStatus run(IProgressMonitor monitor) {
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			if (workspace == null) {
				return Status.CANCEL_STATUS;
			}
			LinkedHashSet<LandmarkUpdateOperation> operations = null;
			synchronized (this) {
				operations = new LinkedHashSet<LandmarkUpdateOperation>(queue);
				queue.clear();
				scheduleTime = NOT_SCHEDULED;
			}
			if (operations != null) {
				try {
					monitor.beginTask(Messages.LandmarkMarkerManager_Updating_Landmark_Markers, operations.size());
					for (LandmarkUpdateOperation runnable : operations) {
						try {
							workspace.run(runnable, runnable.getResource(), IWorkspace.AVOID_UPDATE, monitor);
						} catch (CoreException e) {
							StatusHandler.log(new Status(IStatus.ERROR, JavaUiBridgePlugin.ID_PLUGIN,
									"Could not update landmark marker", e)); //$NON-NLS-1$
						} catch (OperationCanceledException e) {
							return Status.CANCEL_STATUS;
						}
						monitor.worked(1);
					}
				} finally {
					monitor.done();
				}
			}
			return Status.OK_STATUS;
		}
	}
}
