/*******************************************************************************
 * 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.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.reconciler.IReconcilingStrategyExtension;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIMessages;

/**
 * This job holds a queue of updates from the editor (DirtyRegions) to
 * process. When a new request comes in, the current run is canceled, the new
 * request is added to the queue, then the job is re-scheduled.
 * 
 * @author pavery
 */
public class DirtyRegionProcessor extends Job implements IReconciler {
	/** debug flag */
	protected static final boolean DEBUG;

	private static final long UPDATE_DELAY = 750;
	static {
		String value = Platform.getDebugOption("org.eclipse.wst.sse.ui/debug/reconcilerjob"); //$NON-NLS-1$
		DEBUG = value != null && value.equalsIgnoreCase("true"); //$NON-NLS-1$
	}

	private long fDelay;

	/** local queue of dirty regions (created here) to be reconciled */
	private List fDirtyRegionQueue = Collections.synchronizedList(new ArrayList());

	/** document that this reconciler works on */
	private IDocument fDocument = null;

	/**
	 * set true after first install to prevent duplicate work done in the
	 * install method (since install gets called multiple times)
	 */
	private boolean fIsInstalled = false;

	private IProgressMonitor fLocalProgressMonitor = null;

	/**
	 * The partitioning this reconciler uses.
	 */
	private String fPartitioning;

	/** The map of reconciling strategies. */
	private Map fStrategies = new HashMap();

	/** the list of partition types for which there are strategies */
	private List fStrategyTypes = new ArrayList();

	/** the text viewer */
	private ITextViewer fViewer;

	/**
	 * Creates a new StructuredRegionProcessor
	 */
	public DirtyRegionProcessor() {
		
		// init job stuff
		super(SSEUIMessages.proc_dirty_regions_0); //$NON-NLS-1$
		setPriority(Job.LONG);
		setSystem(true);
		setLocalProgressMonitor(new NullProgressMonitor());
		
		// init reconciler stuff
		setDelay(UPDATE_DELAY);
	}

	/**
	 * Adds the given resource to the set of resources that need refreshing.
	 * Synchronized in order to protect the collection during add.
	 * 
	 * @param resource
	 */
	private synchronized void addRequest(DirtyRegion dr) {
        
		List drq = getDirtyRegionQueue();
		// if we already have a request which contains the new request,
		// discare the new request
		int size = drq.size();
		for (int i = 0; i < size; i++) {
			if (contains((DirtyRegion) drq.get(i), dr))
				return;
		}
		// if new request is contains any existing requests,
		// remove those
		for (Iterator it = drq.iterator(); it.hasNext();) {
			if (contains(dr, (DirtyRegion) it.next()))
				it.remove();
		}
		drq.add(dr);
	}

	/**
	 * @param dirtyRegion
	 * @return
	 */
	protected ITypedRegion[] computePartitioning(DirtyRegion dirtyRegion) {       
        int drOffset = dirtyRegion.getOffset();
        int drLength = dirtyRegion.getLength();
        
        return computePartitioning(drOffset, drLength);
	}

	protected ITypedRegion[] computePartitioning(int drOffset, int drLength) {
		IDocument doc = getDocument();
		int docLength = doc.getLength();
		
		ITypedRegion[] tr = new ITypedRegion[0];
		
		if(drOffset > docLength) {
            drOffset = docLength;
            drLength = 0;
        }
        else if(drOffset + drLength > docLength) {
            drLength = docLength - drOffset;
        }
            
		try {
			// dirty region may span multiple partitions
            tr = TextUtilities.computePartitioning(doc, getDocumentPartitioning(), drOffset, drLength, true);
		}
		catch (BadLocationException e) {
            String info = "dr: ["+ drOffset+":"+ drLength + "] doc: [" + docLength + "] "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
			Logger.logException(info, e);
			tr = new ITypedRegion[0];
		}
		return tr;
	}

	/**
	 * @return if the root is parent of possible, return true, otherwise
	 *         return false
	 */
	protected boolean contains(DirtyRegion root, DirtyRegion possible) {

		int rootStart = root.getOffset();
		int rootEnd = rootStart + root.getLength();
		int possStart = possible.getOffset();
		int possEnd = possStart + possible.getLength();
		if (rootStart <= possStart && rootEnd >= possEnd)
			return true;
		return false;
	}

	protected DirtyRegion createDirtyRegion(int offset, int length, String type) {
		DirtyRegion durty = null;
		IDocument doc = getDocument();

		if (doc != null) {
			// safety for BLE
			int docLen = doc.getLength();
            if(offset > docLen) {
                offset = docLen;
                length = 0;
            }
            else if (offset + length >= docLen)
				length = docLen - offset;
			try {
				durty = new DirtyRegion(offset, length, type, doc.get(offset, length));
			}
			catch (BadLocationException e) {
                String info = "dr: ["+ offset+":"+ length + "] doc: [" + docLen + "] "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
                Logger.logException(info, e);
			}
		}
		return durty;
	}

	protected DirtyRegion createDirtyRegion(ITypedRegion tr, String type) {
		return createDirtyRegion(tr.getOffset(), tr.getLength(), type);
	}

	/**
	 * Delay between processing of DirtyRegions.
	 * 
	 * @return
	 */
	protected long getDelay() {
		return fDelay;
	}

	protected List getDirtyRegionQueue() {
		return fDirtyRegionQueue;
	}

	/**
	 * The IDocument on which this reconciler operates
	 * 
	 * @return
	 */
	protected IDocument getDocument() {
		return fDocument;
	}


	public String getDocumentPartitioning() {
		if (fPartitioning == null)
			return IDocumentExtension3.DEFAULT_PARTITIONING;
		return fPartitioning;
	}

	/**
	 * We use our own local progress monitor to cancel long running
	 * strategies/steps. Currently used when widget is disposed (user is
	 * trying to close the editor), and on uninstall.
	 * 
	 * @return the local progress monitor
	 */
	IProgressMonitor getLocalProgressMonitor() {
		return fLocalProgressMonitor;
	}

	/**
	 * Utility method to get partitions of a dirty region
	 * 
	 * @param dirtyRegion
	 * @return
	 */
	protected String[] getPartitions(DirtyRegion dirtyRegion) {
        int drOffset = dirtyRegion.getOffset();
        int drLength = dirtyRegion.getLength();
        return getPartitions(drOffset, drLength);
	}

	protected String[] getPartitions(int drOffset, int drLength) {
		
		ITypedRegion[] regions = new ITypedRegion[0];
		int docLength = getDocument().getLength();
        
        if(drOffset > docLength) {
            drOffset = docLength;
            drLength = 0;
        }
        else if(drOffset + drLength > docLength) {
            drLength = docLength - drOffset;
        }
            
		try {
			regions = TextUtilities.computePartitioning(getDocument(), getDocumentPartitioning(), drOffset, drLength, true);
		}
		catch (BadLocationException e) {
			Logger.logException(e);
			regions = new ITypedRegion[0];
		}
		String[] partitions = new String[regions.length];
		for (int i = 0; i < regions.length; i++)
			partitions[i] = regions[i].getType();
		return partitions;
	}
	
	/**
	 * contentType is actually partitionType
	 * @see IReconciler#getReconcilingStrategy(String)
	 */
	public IReconcilingStrategy getReconcilingStrategy(String contentType) {
		if (fStrategies == null)
			return null;
		return (IReconcilingStrategy) fStrategies.get(contentType);
	}

	/**
	 * This method also synchronized because it accesses the fRequests queue
	 * 
	 * @return an array of the currently requested Nodes to refresh
	 */
	private synchronized DirtyRegion[] getRequests() {
		DirtyRegion[] toRefresh = (DirtyRegion[]) fDirtyRegionQueue.toArray(new DirtyRegion[fDirtyRegionQueue.size()]);
		fDirtyRegionQueue.clear();
		return toRefresh;
	}

	/**
	 * Gets a strategy that is made to handle the given dirtyRegion.
	 * 
	 * @param dirtyRegion
	 * @return a strategy that is made to handle the given dirtyRegion, or the
	 *         default strategy for this reconciler if there isn't one
	 */
	protected IReconcilingStrategy getStrategy(DirtyRegion dirtyRegion) {
		String[] partitions = getPartitions(dirtyRegion);
		// for now just grab first partition type in dirty region
		IReconcilingStrategy rs = null;
		if (partitions.length > 0)
			rs = getReconcilingStrategy(partitions[0]);
		return rs;
	}

	/**
	 * A list of strategy types (keys) for this reconciler. Each strategy
	 * should have a unique key.
	 * 
	 * @return
	 */
	public List getStrategyTypes() {
		return fStrategyTypes;
	}

	/**
	 * Returns the text viewer this reconciler is installed on.
	 * 
	 * @return the text viewer this reconciler is installed on
	 */
	protected ITextViewer getTextViewer() {
		return fViewer;
	}

	/**
	 * @see org.eclipse.jface.text.reconciler.IReconciler#install(ITextViewer)
	 */
	public void install(ITextViewer textViewer) {
		// we might be called multiple times with the same viewer,
		// maybe after being uninstalled as well, so track separately
		if (!isInstalled()) {
			fViewer = textViewer;
			getLocalProgressMonitor().setCanceled(false);
			setInstalled(true);
		}
	}

	/**
	 * The viewer has been set on this Reconciler.
	 * 
	 * @return true if the viewer has been set on this Reconciler, false
	 *         otherwise.
	 */
	public boolean isInstalled() {
		return fIsInstalled;
	}



	/**
	 * Subclasses should implement for specific handling of dirty regions.
	 * 
	 * @param dr
	 */
	protected void process(DirtyRegion dr) {
		// subclasses should implement
	}

	/**
	 * Invoke dirty region processing.
	 * 
	 * @param node
	 */
	public final void processDirtyRegion(DirtyRegion dr) {
		if (dr == null)
			return;
        
		cancel();
		addRequest(dr);
		schedule(getDelay());

		if (DEBUG) {
			System.out.println("added request for: [" + dr.getText() + "]"); //$NON-NLS-1$ //$NON-NLS-2$
			System.out.println("queue size is now: " + getDirtyRegionQueue().size()); //$NON-NLS-1$
		}
	}

	/**
	 * Reinitializes listeners and sets new document on all strategies.
	 * 
	 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#reconcilerDocumentChanged(IDocument)
	 */
	protected void reconcilerDocumentChanged(IDocument document) {
		setDocument(document);
		setDocumentOnAllStrategies(document);
	}

	protected IStatus run(IProgressMonitor monitor) {
		IStatus status = Status.OK_STATUS;
		try {
			DirtyRegion[] toRefresh = getRequests();
			for (int i = 0; i < toRefresh.length; i++) {
				if (monitor.isCanceled())
					throw new OperationCanceledException();
				process(toRefresh[i]);
			}
		}
		catch(Exception e) {
		    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=103676
			// stop errors from popping up a dialog
			// from the job manager
			
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=106052
			// don't log OperationCanceledException
			if(!(e instanceof OperationCanceledException))
				Logger.logException("problem with as-you-type validation", e);
		}
		finally {
			monitor.done();
		}
		return status;
	}

	protected void setDelay(long delay) {
		fDelay = delay;
	}

	public void setDocument(IDocument doc) {
		fDocument = doc;
		setDocumentOnAllStrategies(doc);
	}

	/**
	 * Propagates a new document to all strategies and steps.
	 * 
	 * @param document
	 */
	protected void setDocumentOnAllStrategies(IDocument document) {
		if (isInstalled()) {
			// set document on all regular strategies
			if (fStrategies != null) {
				Iterator e = fStrategies.values().iterator();
				while (e.hasNext()) {
					IReconcilingStrategy strategy = (IReconcilingStrategy) e.next();
					strategy.setDocument(document);
				}
			}
		}
	}

	/**
	 * Sets the document partitioning for this reconciler.
	 * 
	 * @param partitioning
	 *            the document partitioning for this reconciler
	 */
	public void setDocumentPartitioning(String partitioning) {
		fPartitioning = partitioning;
	}

	/**
	 * @param isInstalled
	 *            The isInstalled to set.
	 */
	public void setInstalled(boolean isInstalled) {
		fIsInstalled = isInstalled;
	}

	private void setLocalProgressMonitor(IProgressMonitor pm) {
		fLocalProgressMonitor = pm;
		List strategyTypes = getStrategyTypes();
		// set on all other strategies
		if (!strategyTypes.isEmpty()) {
			Iterator it = strategyTypes.iterator();
			String type = null;
			while (it.hasNext()) {
				type = (String) it.next();
				if (getReconcilingStrategy(type) instanceof IReconcilingStrategyExtension)
					((IReconcilingStrategyExtension) getReconcilingStrategy(type)).setProgressMonitor(pm);
			}
		}
	}

	/**
	 * Sets the strategy for a given contentType (partitionType)
	 * 
	 * @see org.eclipse.jface.text.reconciler.Reconciler#setReconcilingStrategy(org.eclipse.jface.text.reconciler.IReconcilingStrategy,
	 *      java.lang.String)
	 */
	public void setReconcilingStrategy(IReconcilingStrategy strategy, String contentType) {

		if (strategy == null) {
			fStrategies.remove(contentType);
		}
		else {
			fStrategies.put(contentType, strategy);
			if (strategy instanceof IReconcilingStrategyExtension && getLocalProgressMonitor() != null) {
				((IReconcilingStrategyExtension)strategy).setProgressMonitor(getLocalProgressMonitor());
			}	
			strategy.setDocument(fDocument);
		}
		getStrategyTypes().add(contentType);
	}

	/**
	 * @see org.eclipse.jface.text.reconciler.IReconciler#uninstall()
	 */
	public void uninstall() {
		if (isInstalled()) {
			setInstalled(false);
			getLocalProgressMonitor().setCanceled(true);
		}
		setDocument(null);
	}
}