/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.texteditor;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.osgi.framework.Bundle;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResourceStatus;

import org.eclipse.core.filebuffers.IPersistableAnnotationModel;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.IAnnotationMap;

import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.editors.text.EditorsPlugin;
import org.eclipse.ui.internal.editors.text.NLSUtility;

import org.eclipse.ui.editors.text.EditorsUI;


/**
 * Abstract  implementation of a marker-based annotation model.
 * <p>
 * Markers are provided by an underlying source (a subclass responsibility).
 * Markers whose textual range gets deleted during text editing are removed
 * from the model on save. The {@link #updateMarkers(IDocument)} method can be used
 * to force the model to update the source's markers with any changes to their
 * locations due to edits. Clients can register a {@link org.eclipse.ui.texteditor.IMarkerUpdater}
 * objects in order to define the process of marker updating. Registration can be done
 * using the <code>"org.eclipse.ui.markerUpdaters"</code> extension point.
 * </p>
 * <p>
 * Subclasses must implement the following methods:
 * <ul>
 *   <li><code>retrieveMarkers</code></li>
 *   <li><code>isAcceptable</code></li>
 *   <li><code>deleteMarkers</code></li>
 *   <li><code>listenToMarkerChanges</code></li>
 * </ul>
 * </p>
 */
public abstract class AbstractMarkerAnnotationModel extends AnnotationModel implements IPersistableAnnotationModel {

	/** List of annotations whose text range became invalid because of document changes */
	private List<Annotation> fDeletedAnnotations= new ArrayList<>(2);
	/** List of registered and instantiated marker updaters */
	private List<IMarkerUpdater> fInstantiatedMarkerUpdaters= null;
	/** List of registered but not yet instantiated marker updaters */
	private List<IConfigurationElement> fMarkerUpdaterSpecifications= null;

	private static final String ID= "id"; //$NON-NLS-1$

	/**
	 * Retrieves all markers from this model.
	 * <p>
	 * Subclasses must implement this method.</p>
	 *
	 * @return the list of markers
	 * @throws CoreException if there is a problem getting the markers
	 */
	protected abstract IMarker[] retrieveMarkers() throws CoreException;

	/**
	 * Deletes the given markers from this model.
	 * <p>
	 * Subclasses must implement this method.</p>
	 *
	 * @param markers the array of markers
	 * @throws CoreException if there are problems deleting the markers
	 */
	protected abstract void deleteMarkers(IMarker[] markers) throws CoreException;

	/**
	 * Tells the model whether it should listen for marker changes.
	 * <p>
	 * Subclasses must implement this method.</p>
	 *
	 * @param listen <code>true</code> if this model should listen, and
	 *   <code>false</code> otherwise
	 */
	protected abstract void listenToMarkerChanges(boolean listen);

	/**
	 * Determines whether the marker is acceptable as an addition to this model.
	 * If the marker, say, represents an aspect or range of no interest to this
	 * model, the marker is rejected.
	 * <p>
	 * Subclasses must implement this method.</p>
	 *
	 * @param marker the marker
	 * @return <code>true</code> if the marker is acceptable
	 */
	protected abstract boolean isAcceptable(IMarker marker);

	/**
	 * Creates a new annotation model. The annotation model does not manage any
	 * annotations and is not connected to any document.
	 */
	protected AbstractMarkerAnnotationModel() {
	}

	/**
	 * Adds the given marker updater to this annotation model.
	 * It is the client's responsibility to ensure the consistency
	 * of the set of registered marker updaters.
	 *
	 * @param markerUpdater the marker updater to be added
	 */
	protected void addMarkerUpdater(IMarkerUpdater markerUpdater) {
		if (!fInstantiatedMarkerUpdaters.contains(markerUpdater))
			fInstantiatedMarkerUpdaters.add(markerUpdater);
	}

	/**
	 * Removes the given marker updater from this annotation model.
	 *
	 * @param markerUpdater the marker updater to be removed
	 */
	protected void removeMarkerUpdater(IMarkerUpdater markerUpdater) {
		fInstantiatedMarkerUpdaters.remove(markerUpdater);
	}

	/**
	 * Creates a new annotation for the given marker.
	 * <p>
	 * Subclasses may override.</p>
	 *
	 * @param marker the marker
	 * @return the new marker annotation
	 */
	protected MarkerAnnotation createMarkerAnnotation(IMarker marker) {
		return new MarkerAnnotation(marker);
	}

	/**
	 * Handles an unanticipated <code>CoreException</code> in
	 * a standard manner.
	 *
	 * @param exception the exception
	 * @param message a message to aid debugging
	 */
	protected void handleCoreException(CoreException exception, String message) {

		Bundle bundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
		ILog log= Platform.getLog(bundle);
		if (message != null)
			log.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, IStatus.OK, message, exception));
		else
			log.log(exception.getStatus());
	}

	/**
	 * Creates and returns the character position of the given marker based
	 * on its attributes.
	 * <p>
	 * Subclasses may override.</p>
	 *
	 * @param marker the marker
	 * @return the new position or <code>null</code> if the marker attributes do not specify a valid position
	 */
	protected Position createPositionFromMarker(IMarker marker) {

		int start= MarkerUtilities.getCharStart(marker);
		int end= MarkerUtilities.getCharEnd(marker);

		if (start > end) {
			end= start + end;
			start= end - start;
			end= end - start;
		}

		if (start == -1 && end == -1) {
			// marker line number is 1-based
			int line= MarkerUtilities.getLineNumber(marker);
			if (line > 0 && fDocument != null) {
				try {
					start= fDocument.getLineOffset(line - 1);
					end= start;
				} catch (BadLocationException x) {
				}
			}
		}

		if (start > -1 && end > -1)
			return new Position(start, end - start);

		return null;
	}

	/**
	 * Creates an annotation for the given marker and adds it to this model.
	 * Does nothing if the marker is not acceptable to this model.
	 *
	 * @param marker the marker
	 * @see #isAcceptable(IMarker)
	 */
	protected final void addMarkerAnnotation(IMarker marker) {

		if (isAcceptable(marker)) {
			Position p= createPositionFromMarker(marker);
			if (p != null)
				try {
					MarkerAnnotation annotation= createMarkerAnnotation(marker);
					if (annotation != null)
						addAnnotation(annotation, p, false);
				} catch (BadLocationException e) {
					// ignore invalid position
				}
		}
	}

	/**
	 * Connects to the source of markers as marker change listener.
	 * @see AnnotationModel#connected()
	 */
	@Override
	protected void connected() {

		listenToMarkerChanges(true);

		try {
			catchupWithMarkers();
		} catch (CoreException x) {
			if (x.getStatus().getCode() != IResourceStatus.RESOURCE_NOT_FOUND)
				handleCoreException(x, TextEditorMessages.AbstractMarkerAnnotationModel_connected);
		}

		fireModelChanged();
	}

	/**
	 * Installs all marker updaters for this marker annotation model.
	 */
	private void installMarkerUpdaters() {

		// initialize lists - indicates that the initialization happened
		fInstantiatedMarkerUpdaters= new ArrayList<>(2);
		HashMap<String, Integer> markerUpdaterOrderMap = new HashMap<>(2);
		LinkedList<IConfigurationElement> markerUpdaterSpecificationsLinkedList= new LinkedList<>();

		// populate list
		IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(EditorsUI.PLUGIN_ID, "markerUpdaters"); //$NON-NLS-1$
		if (extensionPoint != null) {
			IConfigurationElement[] elements= extensionPoint.getConfigurationElements();
			for (int i= 0; i < elements.length; i++) {
				markerUpdaterSpecificationsLinkedList.add(elements[i]);
				markerUpdaterOrderMap.put(elements[i].getAttribute(ID), new Integer(i));
			}
			//start sorting based on required-updater definition
			HashMap<String, ArrayList<String>> markerUpdaterRequiredByOrderMap= new HashMap<>(2);
			for (int i= 0; i < elements.length; i++) {
				// Required marker should execute before other updater markers
				IConfigurationElement[] requiredUpdaters= elements[i].getChildren("required-updater"); //$NON-NLS-1$
				if (requiredUpdaters.length > 0) {
					//ArrayList requiredUpdaters= new ArrayList(2);
					for (int j= 0; j < requiredUpdaters.length; j++) { // If required updaters have been defined
						String requiredID= requiredUpdaters[j].getAttribute(ID);
						// If required ID is not a valid id
						if (requiredID == null || (markerUpdaterOrderMap.get(requiredID) == null)) { // ID missing or invalid - log the message and move to next contribution
							String msg= NLSUtility.format(TextEditorMessages.AbstractMarkerAnnotationModel_updaterInvalidDefinition, new Object[] { elements[i].getAttribute(ID), requiredID });
							EditorsPlugin.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, msg));
							continue;
						}
						// Updating requiredByUpdaters to identify and log error for cyclic Dependency like A required B, B required C, C required D and D required A
						// or A requires B and B requires A

						ArrayList<String> requiredByUpdaters;
						if (markerUpdaterRequiredByOrderMap.get(requiredID) == null) {
							requiredByUpdaters= new ArrayList<>(2);
						}
						else {
							requiredByUpdaters= markerUpdaterRequiredByOrderMap.get(requiredID);
						}
						// Build up extended required id list to identify Case 2
						if (markerUpdaterRequiredByOrderMap.get(elements[i].getAttribute(ID)) != null) {
							ArrayList<String> requiredByList= markerUpdaterRequiredByOrderMap.get(elements[i].getAttribute(ID));
							requiredByUpdaters.addAll(requiredByList);
						}
						if (requiredByUpdaters.contains(requiredID)) { //log error if marker ID is in the required list of required ID
							String msg= NLSUtility.format(TextEditorMessages.AbstractMarkerAnnotationModel_markerUpdaterCyclicDefinition, new Object[] { elements[i].getAttribute(ID), requiredID });
							EditorsPlugin.log(new Status(IStatus.ERROR, PlatformUI.PLUGIN_ID, msg));
							continue;
						}
						requiredByUpdaters.add(elements[i].getAttribute(ID));
						markerUpdaterRequiredByOrderMap.put(requiredID, requiredByUpdaters);

						Integer requiredLocation= markerUpdaterOrderMap.get(requiredID);
						if (requiredLocation.intValue() > markerUpdaterOrderMap.get(elements[i].getAttribute(ID)).intValue()) { // If required marker is not ordered before
							int newLocation= (markerUpdaterOrderMap.get(elements[i].getAttribute(ID)).intValue() == 0) ? 0 : (markerUpdaterOrderMap.get(elements[i]
									.getAttribute(ID)).intValue() - 1);
							IConfigurationElement requiredMarker= markerUpdaterSpecificationsLinkedList.remove(requiredLocation.intValue());
							markerUpdaterSpecificationsLinkedList.add(newLocation, requiredMarker); // Put the required location before the marker
							markerUpdaterOrderMap.put(requiredID, new Integer(newLocation));
							markerUpdaterOrderMap.put(elements[i].getAttribute(ID), new Integer(newLocation + 1));
						}
					}
				}
			}
			fMarkerUpdaterSpecifications= new ArrayList<>(markerUpdaterSpecificationsLinkedList);
			//end sorting

		}
	}

	/**
	 * Uninstalls all marker updaters.
	 */
	private void uninstallMarkerUpdaters() {
		if (fInstantiatedMarkerUpdaters != null) {
			fInstantiatedMarkerUpdaters.clear();
			fInstantiatedMarkerUpdaters= null;
		}

		if (fMarkerUpdaterSpecifications != null) {
			fMarkerUpdaterSpecifications.clear();
			fMarkerUpdaterSpecifications= null;
		}
	}

	/**
	 * Removes the marker change listener.
	 * @see AnnotationModel#disconnected()
	 */
	@Override
	protected void disconnected() {
		listenToMarkerChanges(false);
		uninstallMarkerUpdaters();
	}

	/**
	 * Returns the position known to this annotation model for the given marker.
	 *
	 * @param marker the marker
	 * @return the position, or <code>null</code> if none
	 */
	public Position getMarkerPosition(IMarker marker) {
		MarkerAnnotation a= getMarkerAnnotation(marker);
		if (a != null) {
			return getAnnotationMap().get(a);
		}
		return null;
	}

	/**
	 * Updates the annotation corresponding to the given marker which has changed
	 * in some way.
	 * <p>
	 * Subclasses may override.</p>
	 *
	 * @param marker the marker
	 */
	protected void modifyMarkerAnnotation(IMarker marker) {
		MarkerAnnotation a= getMarkerAnnotation(marker);
		if (a != null) {
			Position p= createPositionFromMarker(marker);
			if (p != null) {
				a.update();
				modifyAnnotationPosition(a, p, false);
			}
		} else
			addMarkerAnnotation(marker);
	}

	@Override
	protected void removeAnnotations(List<? extends Annotation> annotations, boolean fireModelChanged, boolean modelInitiated) {
		if (annotations != null && annotations.size() > 0) {

			List<Annotation> markerAnnotations= new ArrayList<>();
			for (Iterator<? extends Annotation> e= annotations.iterator(); e.hasNext();) {
				Annotation a= e.next();
				if (a instanceof MarkerAnnotation)
					markerAnnotations.add(a);

				// remove annotations from annotation model
				removeAnnotation(a, false);
			}

			if (markerAnnotations.size() > 0) {

				if (modelInitiated) {
					// if model initiated also remove it from the marker manager

					listenToMarkerChanges(false);
					try {

						IMarker[] m= new IMarker[markerAnnotations.size()];
						for (int i= 0; i < m.length; i++) {
							MarkerAnnotation ma = (MarkerAnnotation) markerAnnotations.get(i);
							m[i]= ma.getMarker();
						}
						deleteMarkers(m);

					} catch (CoreException x) {
						handleCoreException(x, TextEditorMessages.AbstractMarkerAnnotationModel_removeAnnotations);
					}
					listenToMarkerChanges(true);

				} else {
					// remember deleted annotations in order to remove their markers later on
					fDeletedAnnotations.addAll(markerAnnotations);
				}
			}

			if (fireModelChanged)
				fireModelChanged();
		}
	}

	/**
	 * Removes the annotation corresponding to the given marker. Does nothing
	 * if there is no annotation for this marker.
	 *
	 * @param marker the marker
	 */
	protected final void removeMarkerAnnotation(IMarker marker) {
		MarkerAnnotation a= getMarkerAnnotation(marker);
		if (a != null) {
			removeAnnotation(a, false);
		}
	}

	/**
	 * Re-populates this model with annotations for all markers retrieved
	 * from the maker source via <code>retrieveMarkers</code>.
	 *
	 * @throws CoreException if there is a problem getting the markers
	 */
	private void catchupWithMarkers() throws CoreException {

		for (Iterator<Annotation> e=getAnnotationIterator(false); e.hasNext();) {
			Annotation a= e.next();
			if (a instanceof MarkerAnnotation)
				removeAnnotation(a, false);
		}

		IMarker[] markers= retrieveMarkers();
		if (markers != null) {
			for (int i= 0; i < markers.length; i++)
				addMarkerAnnotation(markers[i]);
		}
	}

	/**
	 * Returns this model's annotation for the given marker.
	 *
	 * @param marker the marker
	 * @return the annotation, or <code>null</code> if none
	 */
	public final MarkerAnnotation getMarkerAnnotation(IMarker marker) {
		Iterator<Annotation> e= getAnnotationIterator(false);
		while (e.hasNext()) {
			Object o= e.next();
			if (o instanceof MarkerAnnotation) {
				MarkerAnnotation a= (MarkerAnnotation) o;
				if (marker.equals(a.getMarker())) {
					return a;
				}
			}
		}
		return null;
	}

	/**
	 * Creates a marker updater as specified in the given configuration element.
	 *
	 * @param element the configuration element
	 * @return the created marker updater or <code>null</code> if none could be created
	 */
	private IMarkerUpdater createMarkerUpdater(IConfigurationElement element) {
		try {
			return (IMarkerUpdater) element.createExecutableExtension("class"); //$NON-NLS-1$
		} catch (CoreException x) {
			handleCoreException(x, TextEditorMessages.AbstractMarkerAnnotationModel_createMarkerUpdater);
		}

		return null;
	}

	/**
	 * Checks whether a marker updater is registered for the type of the
	 * given marker but not yet instantiated. If so, the method instantiates
	 * the marker updater and registers it with this model.
	 *
	 * @param marker the marker for which to look for an updater
	 * @since 2.0
	 */
	private void checkMarkerUpdaters(IMarker marker) {
		List<IConfigurationElement> toBeDeleted= new ArrayList<>();
		for (int i= 0; i < fMarkerUpdaterSpecifications.size(); i++) {
			IConfigurationElement spec= fMarkerUpdaterSpecifications.get(i);
			String markerType= spec.getAttribute("markerType"); //$NON-NLS-1$
			if (markerType == null || MarkerUtilities.isMarkerType(marker, markerType)) {
				toBeDeleted.add(spec);
				IMarkerUpdater updater= createMarkerUpdater(spec);
				if (updater != null)
					addMarkerUpdater(updater);
			}
		}

		for (int i= 0; i < toBeDeleted.size(); i++)
			fMarkerUpdaterSpecifications.remove(toBeDeleted.get(i));
	}

	/**
	 * Updates the given marker according to the given position in the given
	 * document. If the given position is <code>null</code>, the marker is
	 * assumed to carry the correct positional information. If it is detected
	 * that the marker is invalid and should thus be deleted, this method
	 * returns <code>false</code>.
	 * <p>
	 * <strong>Note:</strong> This implementation queries the registered
	 * {@linkplain IMarkerUpdater}s. If any of these updaters returns
	 * <code>false</code> this method also returns <code>false</code>.
	 * </p>
	 *
	 * @param marker the marker to be updated
	 * @param document the document into which the given position points
	 * @param position the current position of the marker inside the given document
	 * @return <code>false</code> if the marker is invalid
	 * @throws CoreException if there is a problem updating the marker
	 * @since 2.0
	 * @deprecated use <code>updateMarker(IDocument, IMarker, Position)</code> instead. This method will be changed to protected.
	 */
	@Deprecated
	public boolean updateMarker(IMarker marker, IDocument document, Position position) throws CoreException {

		if (fMarkerUpdaterSpecifications == null)
			installMarkerUpdaters();

		if (!fMarkerUpdaterSpecifications.isEmpty())
			checkMarkerUpdaters(marker);

		boolean isOK= true;

		for (int i= 0; i < fInstantiatedMarkerUpdaters.size();  i++) {
			IMarkerUpdater updater= fInstantiatedMarkerUpdaters.get(i);
			String markerType= updater.getMarkerType();
			if (markerType == null || MarkerUtilities.isMarkerType(marker, markerType)) {

				if (position == null) {
					/* compatibility code */
					position= createPositionFromMarker(marker);
				}

				isOK= (isOK && updater.updateMarker(marker, document, position));
			}
		}

		return isOK;
	}

	/**
	 * Updates the given marker according to the given position in the given
	 * document. If the given position is <code>null</code>, the marker is
	 * assumed to carry the correct positional information. If it is detected
	 * that the marker is invalid and should thus be deleted, this method
	 * returns <code>false</code>.
	 *
	 * @param marker the marker to be updated
	 * @param document the document into which the given position points
	 * @param position the current position of the marker inside the given document
	 * @return <code>false</code> if the marker is invalid
	 * @throws CoreException if there is a problem updating the marker
	 * @since 3.0
	 */
	public boolean updateMarker(IDocument document, IMarker marker, Position position) throws CoreException {
		listenToMarkerChanges(false);
		try {
			return updateMarker(marker, document, position);
		} finally {
			listenToMarkerChanges(true);
		}
	}

	/**
	 * Updates the markers managed by this annotation model by calling
	 * all registered marker updaters (<code>IMarkerUpdater</code>).
	 *
	 * @param document the document to which this model is currently connected
	 * @throws CoreException if there is a problem updating the markers
	 */
	public void updateMarkers(IDocument document) throws CoreException {

		Assert.isTrue(fDocument == document);

		IAnnotationMap annotationMap= getAnnotationMap();

		if (annotationMap.size() == 0 && fDeletedAnnotations.size() == 0)
			return;

		if (fMarkerUpdaterSpecifications == null)
			installMarkerUpdaters();

		listenToMarkerChanges(false);

		try {

			// update all markers with the positions known by the annotation model
			for (Iterator<Annotation> e= getAnnotationIterator(false); e.hasNext();) {
				Object o= e.next();
				if (o instanceof MarkerAnnotation) {
					MarkerAnnotation a= (MarkerAnnotation) o;
					IMarker marker= a.getMarker();
					Position position= annotationMap.get(a);
					if ( !updateMarker(marker, document, position)) {
						if ( !fDeletedAnnotations.contains(a))
							fDeletedAnnotations.add(a);
					}
				}
			}

			if (!fDeletedAnnotations.isEmpty()) {
				removeAnnotations(fDeletedAnnotations, true, true);
				fDeletedAnnotations.clear();
			}

		} finally {

			listenToMarkerChanges(true);

		}
	}

	/**
	 * Resets all the markers to their original state.
	 */
	public void resetMarkers() {

		// re-initializes the positions from the markers
		for (Iterator<Annotation> e= getAnnotationIterator(false); e.hasNext();) {
			Object o= e.next();
			if (o instanceof MarkerAnnotation) {
				MarkerAnnotation a= (MarkerAnnotation) o;
				Position p= createPositionFromMarker(a.getMarker());
				if (p != null) {
					removeAnnotation(a, false);
					try {
						addAnnotation(a, p, false);
					} catch (BadLocationException e1) {
						// ignore invalid position
					}
				}
			}
		}

		// add the markers of deleted positions back to the annotation model
		for (Iterator<Annotation> e= fDeletedAnnotations.iterator(); e.hasNext();) {
			Object o= e.next();
			if (o instanceof MarkerAnnotation) {
				MarkerAnnotation a= (MarkerAnnotation) o;
				Position p= createPositionFromMarker(a.getMarker());
				if (p != null)
					try {
						addAnnotation(a, p, false);
					} catch (BadLocationException e1) {
						// ignore invalid position
					}
			}
		}
		fDeletedAnnotations.clear();

		// fire annotation model changed
		fireModelChanged();
	}

	@Override
	public void commit(IDocument document) throws CoreException {
		updateMarkers(document);
	}

	@Override
	public void revert(IDocument document) {
		resetMarkers();
	}

	@Override
	public void reinitialize(IDocument document) {
		resetMarkers();
	}
}
