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

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
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.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;

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

	/** 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);

		// 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;
	}

	/**
	 * 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) {
		// we don't use this, we only have a validator strategy
		return null;
	}

	/**
	 * 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;
	}

	/**
	 * 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 viewe.r,
		// maybe after being uninstalled as well, so track separately
		if (!isInstalled()) {
			fViewer = textViewer;
			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); //$NON-NLS-1$
		}
		finally {
			monitor.done();
		}
		return status;
	}

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

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

	/**
	 * 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;
	}

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