/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui.internal.reconcile;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcileResult;
import org.eclipse.jface.text.reconciler.IReconcileStep;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
import org.eclipse.jface.text.source.IAnnotationModel;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.ui.internal.IReleasable;
import org.eclipse.wst.sse.ui.internal.ITemporaryAnnotation;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.StructuredMarkerAnnotation;


/**
 * A base ReconcilingStrategy. Subclasses must implement
 * createReconcileSteps().
 * 
 * @author pavery
 */
public abstract class AbstractStructuredTextReconcilingStrategy implements IReconcilingStrategy, IReconcilingStrategyExtension, IReleasable {

    /** debug flag */
    protected static final boolean DEBUG;
    static {
        String value = Platform.getDebugOption("org.eclipse.wst.sse.ui/debug/reconcilerjob"); //$NON-NLS-1$
        DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
    }
    
	// these limits are safetys for "runaway" validation cases
	// should be used to safeguard potentially dangerous loops or potentially
	// long annotations
	// (since the painter seems to affect performance when painting long
	// annotations)
	public static final int ANNOTATION_LENGTH_LIMIT = 25;
	public static final int ELEMENT_ERROR_LIMIT = 25;
    
	protected IDocument fDocument = null;
	protected IReconcileStep fFirstStep = null;
	protected IProgressMonitor fProgressMonitor = null;
	protected ITextEditor fTextEditor = null;
    private Comparator fComparator;

	// list of "validator" annotations
	// for gray/un-gray capability
	private HashSet fMarkerAnnotations = new HashSet();
	
	/**
	 * Creates a new strategy. The editor parameter is for access to the
	 * annotation model.
	 * 
	 * @param editor
	 */
	public AbstractStructuredTextReconcilingStrategy(ITextEditor editor) {
		fTextEditor = editor;
		init();
	}

	/**
	 * This is where we add results to the annotationModel, doing any special
	 * "extra" processing.
	 */
	protected void addResultToAnnotationModel(IReconcileResult result) {
		if (!(result instanceof TemporaryAnnotation))
			return;
		// can be null when closing the editor
		if (getAnnotationModel() != null) {
			TemporaryAnnotation tempAnnotation = (TemporaryAnnotation) result;
			
			StructuredMarkerAnnotation sma = getCorrespondingMarkerAnnotation(tempAnnotation);
			if(sma != null) {
				// un-gray out the marker annotation
				sma.setGrayed(false);
			}
			
			getAnnotationModel().addAnnotation(tempAnnotation, tempAnnotation.getPosition());
		}
	}

	/**
	 * @param object
	 * @return if this strategy is responisble for adding this type of key
	 */
	protected boolean canHandlePartition(String partition) {
		String[] haystack = getPartitionTypes();
		for (int i = 0; i < haystack.length; i++) {
			if (haystack[i].equals(partition))
				return true;
		}
		return false;
	}

	/**
	 * @param step
	 * @return
	 */
	protected boolean containsStep(IReconcileStep step) {
		if (fFirstStep instanceof StructuredReconcileStep)
			return ((StructuredReconcileStep) fFirstStep).isSiblingStep(step);
		return false;
	}

	/**
	 * This is where you should create the steps for this strategy
	 */
	abstract public void createReconcileSteps();

	/**
	 * Remove ALL temporary annotations that this strategy can handle.
	 */
	protected TemporaryAnnotation[] getAllAnnotationsToRemove() {
		List removals = new ArrayList();
		IAnnotationModel annotationModel = getAnnotationModel();
		if (annotationModel != null) {
			Iterator i = annotationModel.getAnnotationIterator();
			while (i.hasNext()) {
				Object obj = i.next();
				if (!(obj instanceof ITemporaryAnnotation))
					continue;

				ITemporaryAnnotation annotation = (ITemporaryAnnotation) obj;
				ReconcileAnnotationKey key = (ReconcileAnnotationKey) annotation.getKey();
				// then if this strategy knows how to add/remove this
				// partition type
				if (canHandlePartition(key.getPartitionType()) && containsStep(key.getStep()))
					removals.add(annotation);
			}
		}
		return (TemporaryAnnotation[]) removals.toArray(new TemporaryAnnotation[removals.size()]);
	}

	protected IAnnotationModel getAnnotationModel() {
		IAnnotationModel model = null;
		if (fTextEditor != null && fTextEditor.getEditorInput() != null) {
			model = fTextEditor.getDocumentProvider().getAnnotationModel(fTextEditor.getEditorInput());
		}
		return model;
	}

	protected TemporaryAnnotation[] getAnnotationsToRemove(DirtyRegion dr) {
		IStructuredDocumentRegion[] sdRegions = getStructuredDocumentRegions(dr);
		List remove = new ArrayList();
		IAnnotationModel annotationModel = getAnnotationModel();
		// can be null when closing the editor
		if (getAnnotationModel() != null) {
			
			// clear validator annotations
			fMarkerAnnotations.clear();
			
			Iterator i = annotationModel.getAnnotationIterator();
			while (i.hasNext()) {
				
				Object obj = i.next();
				
				// check if it's a validator marker annotation
				// if it is save it for comparision later (to "gray" icons)
				if(obj instanceof StructuredMarkerAnnotation) {
					StructuredMarkerAnnotation sma = (StructuredMarkerAnnotation)obj;
					
					if(sma.getAnnotationType() == TemporaryAnnotation.ANNOT_ERROR || sma.getAnnotationType() == TemporaryAnnotation.ANNOT_WARNING)
						fMarkerAnnotations.add(sma);
				}
				
				if (!(obj instanceof TemporaryAnnotation))
					continue;

				TemporaryAnnotation annotation = (TemporaryAnnotation) obj;
				ReconcileAnnotationKey key = (ReconcileAnnotationKey) annotation.getKey();
				
				// then if this strategy knows how to add/remove this
				// partition type
				if (canHandlePartition(key.getPartitionType()) && containsStep(key.getStep())) {
					if (key.getScope() == ReconcileAnnotationKey.PARTIAL && overlaps(annotation.getPosition(), sdRegions)) {
						remove.add(annotation);
					}
					else if (key.getScope() == ReconcileAnnotationKey.TOTAL) {
						remove.add(annotation);
					}
				}
			}
		}
		return (TemporaryAnnotation[]) remove.toArray(new TemporaryAnnotation[remove.size()]);
	}

	/**
	 * Returns the corresponding node for the StructuredDocumentRegion.
	 * 
	 * @param sdRegion
	 * @return the corresponding node for sdRegion
	 */
	protected IndexedRegion getCorrespondingNode(IStructuredDocumentRegion sdRegion) {
		IStructuredModel sModel = StructuredModelManager.getModelManager().getExistingModelForRead(fDocument);
        IndexedRegion indexedRegion = null;
        try {
            if (sModel != null) 
                indexedRegion = sModel.getIndexedRegion(sdRegion.getStart());    
        } finally {
            if (sModel != null)
                sModel.releaseFromRead();
        }
        return indexedRegion;
    }

	/**
	 * The IFile that this strategy is operating on (the file input for the
	 * TextEditor)
	 * 
	 * @return the IFile that this strategy is operating on
	 */
	protected IFile getFile() {
		if (fTextEditor == null)
			return null;
		IEditorInput input = fTextEditor.getEditorInput();
		if (!(input instanceof IFileEditorInput))
			return null;
		return ((IFileEditorInput) input).getFile();
	}

	/**
	 * Gets partition types from all steps in this strategy.
	 * 
	 * @return parition types from all steps
	 */
	public String[] getPartitionTypes() {
		if (fFirstStep instanceof StructuredReconcileStep)
			return ((StructuredReconcileStep) fFirstStep).getPartitionTypes();
		return new String[0];
	}

	/**
	 * Returns the appropriate (first) IStructuredDocumentRegion for the given
	 * dirtyRegion.
	 * 
	 * @param dirtyRegion
	 * @return the appropriate StructuredDocumentRegion for the given
	 *         dirtyRegion.
	 */
	private IStructuredDocumentRegion getStructuredDocumentRegion(int offset) {
		IStructuredDocumentRegion sdRegion = null;
		if (fDocument instanceof IStructuredDocument) {
			sdRegion = ((IStructuredDocument) fDocument).getRegionAtCharacterOffset(offset);
		}
		return sdRegion;
	}

	private IStructuredDocumentRegion[] getStructuredDocumentRegions(DirtyRegion dr) {
		int offset = dr.getOffset();
		int end = offset + dr.getLength();
		List regions = new ArrayList();
		IStructuredDocumentRegion r = getStructuredDocumentRegion(offset);
		while (r != null && r.getStartOffset() <= end) {
			if (!r.isDeleted())
				regions.add(r);
			r = r.getNext();
		}
		return (IStructuredDocumentRegion[]) regions.toArray(new IStructuredDocumentRegion[regions.size()]);
	}

	public void init() {
		createReconcileSteps();
	}

	/**
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#initialReconcile()
	 */
	public void initialReconcile() {
		// do nothing
	}

	/**
	 * @return
	 */
	protected boolean isCanceled() {
		if (DEBUG && (fProgressMonitor != null && fProgressMonitor.isCanceled()))
			System.out.println("** STRATEGY CANCELED **:" + this.getClass().getName()); //$NON-NLS-1$
		return fProgressMonitor != null && fProgressMonitor.isCanceled();
	}

	/**
	 * Checks if this position overlaps any of the StructuredDocument regions'
	 * correstponding IndexedRegion.
	 * 
	 * @param pos
	 * @param sdRegions
	 * @return true if the position overlaps any of the regions, otherwise
	 *         false.
	 */
	protected boolean overlaps(Position pos, IStructuredDocumentRegion[] sdRegions) {
		int start = -1;
		int end = -1;
		for (int i = 0; i < sdRegions.length; i++) {
		    if(!sdRegions[i].isDeleted()) {
    			IndexedRegion corresponding = getCorrespondingNode(sdRegions[i]);
                if(corresponding != null) {
        			if (start == -1 || start > corresponding.getStartOffset())
        				start = corresponding.getStartOffset();
        			if (end == -1 || end < corresponding.getEndOffset())
        				end = corresponding.getEndOffset();
                }
            }
		}
		return pos.overlapsWith(start, end - start);
	}

	/**
	 * Process the results from the reconcile steps in this strategy.
	 * 
	 * @param results
	 */
	private void process(final IReconcileResult[] results) {
		if (DEBUG)
			System.out.println("[trace reconciler] > STARTING PROCESS METHOD with (" + results.length + ") results"); //$NON-NLS-1$ //$NON-NLS-2$

		if (results == null)
			return;

		for (int i = 0; i<results.length && i<ELEMENT_ERROR_LIMIT && !isCanceled(); i++) {

			if (isCanceled()) {
                if(DEBUG)
				    System.out.println("[trace reconciler] >** PROCESS (adding) WAS CANCELLED **"); //$NON-NLS-1$
				return;
			}
			addResultToAnnotationModel(results[i]);
		}
        
		if (DEBUG) {
			StringBuffer traceString = new StringBuffer();
			for (int j = 0; j < results.length; j++)
				traceString.append("\n (+) :" + results[j] + ":\n"); //$NON-NLS-1$ //$NON-NLS-2$
			System.out.println("[trace reconciler] > PROCESSING (" + results.length + ") results in AbstractStructuredTextReconcilingStrategy " + traceString); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	/**
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.reconciler.DirtyRegion,
	 *      org.eclipse.jface.text.IRegion)
	 */
	public void reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {

		// external files may be null
		if (isCanceled() || fFirstStep == null)
			return;

        TemporaryAnnotation[] annotationsToRemove = new TemporaryAnnotation[0];
        IReconcileResult[] annotationsToAdd = new IReconcileResult[0];
        StructuredReconcileStep structuredStep = (StructuredReconcileStep) fFirstStep;
        
        annotationsToRemove = getAnnotationsToRemove(dirtyRegion);
        annotationsToAdd = structuredStep.reconcile(dirtyRegion, subRegion);
        
        smartProcess(annotationsToRemove, annotationsToAdd);
	}
    
	/**
	 * @param partition
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#reconcile(org.eclipse.jface.text.IRegion)
	 */
	public void reconcile(IRegion partition) {
		// not used, we use:
        // reconcile(DirtyRegion dirtyRegion, IRegion subRegion)
	}

	/**
	 * Calls release() on all the steps in this strategy. Currently done in
	 * StructuredRegionProcessor.SourceWidgetDisposeListener#widgetDisposed(...)
	 */
	public void release() {
		// release steps (each step calls release on the next)
		if (fFirstStep != null && fFirstStep instanceof IReleasable)
			((IReleasable) fFirstStep).release();
		// we don't to null out the steps, in case
		// it's reconfigured later
	}

	private void removeAnnotations(TemporaryAnnotation[] annotationsToRemove) {
		
		IAnnotationModel annotationModel = getAnnotationModel();
		// can be null when closing the editor
		if (annotationModel != null) {
			for (int i = 0; i < annotationsToRemove.length; i++) {
				if (isCanceled()) {
                    if(DEBUG)
					    System.out.println("[trace reconciler] >** REMOVAL WAS CANCELLED **"); //$NON-NLS-1$
					return;
				}
				StructuredMarkerAnnotation sma = getCorrespondingMarkerAnnotation(annotationsToRemove[i]);
				if(sma != null) {
					// gray out the marker annotation
					sma.setGrayed(true);
				}
				// remove the temp one
				annotationModel.removeAnnotation(annotationsToRemove[i]);
				
			}
		}
        
		if (DEBUG) {
			StringBuffer traceString = new StringBuffer();
			for (int i = 0; i < annotationsToRemove.length; i++)
				traceString.append("\n (-) :" + annotationsToRemove[i] + ":\n"); //$NON-NLS-1$ //$NON-NLS-2$
			System.out.println("[trace reconciler] > REMOVED (" + annotationsToRemove.length + ") annotations in AbstractStructuredTextReconcilingStrategy :" + traceString); //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

    private StructuredMarkerAnnotation getCorrespondingMarkerAnnotation(TemporaryAnnotation tempAnnotation) {
		
		Iterator it = fMarkerAnnotations.iterator();
		while (it.hasNext()) {
			StructuredMarkerAnnotation markerAnnotation = (StructuredMarkerAnnotation) it.next();
			String message = ""; //$NON-NLS-1$
			try {
				message = (String) markerAnnotation.getMarker().getAttribute(IMarker.MESSAGE);
			} 
			catch (CoreException e) {
				if(DEBUG)
					Logger.logException(e);
			}
			// it would be nice to check line number here...
			if(message != null && message.equals(tempAnnotation.getText()))
				return markerAnnotation;
		}
		return null;
	}

	private void removeAllAnnotations() {
        removeAnnotations(getAllAnnotationsToRemove());
    }

	/**
	 * Set the document for this strategy.
	 * 
	 * @param document
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
	 */
	public void setDocument(IDocument document) {

		// remove all old annotations since it's a new document
	    removeAllAnnotations();

		if (document == null)
			release();

		fDocument = document;
		if (fFirstStep != null)
			fFirstStep.setInputModel(new DocumentAdapter(document));
	}

	/**
	 * @param monitor
	 * @see org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension#setProgressMonitor(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void setProgressMonitor(IProgressMonitor monitor) {
		fProgressMonitor = monitor;
		if (fFirstStep != null)
			fFirstStep.setProgressMonitor(fProgressMonitor);
	}

	/**
	 * Check if the annotation is already there, if it is, no need to 
     * remove or add again. this will avoid a lot of flickering behavior...
	 * 
	 * @param annotationsToRemove
	 * @param annotationsToAdd
	 */
	protected void smartProcess(TemporaryAnnotation[] annotationsToRemove, IReconcileResult[] annotationsToAdd) {
        
        // TODO: investigate a better algorithm, 
        // also see if this is a bad performance hit.
        
        Comparator comp = getAnnotationComparator();
        List sortedRemovals = Arrays.asList(annotationsToRemove);
	    Collections.sort(sortedRemovals, comp);
        
        List sortedAdditions = Arrays.asList(annotationsToAdd);
        Collections.sort(sortedAdditions, comp);
        
        List filteredRemovals = new ArrayList(sortedRemovals);
        List filteredAdditions = new ArrayList(sortedAdditions);
        
        boolean ignore = false;
        int lastFoundAdded = 0;
        for(int i=0; i<sortedRemovals.size(); i++) {
            TemporaryAnnotation removal = (TemporaryAnnotation)sortedRemovals.get(i);       
            for(int j=lastFoundAdded; j<sortedAdditions.size(); j++) {             
                TemporaryAnnotation addition = (TemporaryAnnotation)sortedAdditions.get(j);
                // quick position check here
                if(removal.getPosition().equals(addition.getPosition())) {
                    lastFoundAdded = j;
                    // remove performs TemporaryAnnotation.equals()
                    // which checks text as well
                    filteredAdditions.remove(addition);
                    ignore = true;
                    if(DEBUG)
                        System.out.println(" ~ smart process ignoring: " + removal.getPosition().getOffset()); //$NON-NLS-1$
                    break;
                }
            }
            if(ignore) {
                filteredRemovals.remove(removal);
            }
            ignore = false;
        }
        
        removeAnnotations((TemporaryAnnotation[])filteredRemovals.toArray(new TemporaryAnnotation[filteredRemovals.size()]));
        process((IReconcileResult[])filteredAdditions.toArray(new IReconcileResult[filteredAdditions.size()]));
	}
    
    private Comparator getAnnotationComparator() {
        if(fComparator == null) {
            fComparator = new Comparator( ) {
                public int compare(Object arg0, Object arg1) {
                    TemporaryAnnotation ta1 = (TemporaryAnnotation)arg0;
                    TemporaryAnnotation ta2 = (TemporaryAnnotation)arg1;
                    return ta1.getPosition().getOffset() - ta2.getPosition().getOffset();
                }
            };
        }
        return fComparator;
    }
	
	public boolean isTotalScope() {
		return false;
	}
}
