package org.eclipse.wst.sse.ui.internal.reconcile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentDescription;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ITextInputListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcilingStrategy;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.wst.sse.ui.internal.IReleasable;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorBuilder;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorMetaData;
import org.eclipse.wst.sse.ui.internal.reconcile.validator.ValidatorStrategy;

/**
 * Adds to DirtyRegionProcessor Job:
 * 
 * - IDocumentListener
 * - ValidatorStrategy
 * - Text viewer(dispose, input changed) listeners.
 * - default and validator strategies
 * - DirtyRegion processing logic.
 */
public class DocumentRegionProcessor extends DirtyRegionProcessor implements IDocumentListener{

	/**
	 * Reconclies the entire document when the document in the viewer is
	 * changed. This happens when the document is initially opened, as well as
	 * after a save-as.
	 * 
	 * Also see processPostModelEvent(...) for similar behavior when document
	 * for the model is changed.
	 */
	private class SourceTextInputListener implements ITextInputListener {

		public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
			// do nothing
		}

		public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
			handleInputDocumentChanged(oldInput, newInput);
		}
	}

	/** for initital reconcile when document is opened */
	private SourceTextInputListener fTextInputListener = null;

	/**
	 * The strategy that runs validators contributed via
	 * <code>org.eclipse.wst.sse.ui.extensions.sourcevalidation</code>
	 * extension point
	 */
	private ValidatorStrategy fValidatorStrategy;
	
	private final String SSE_EDITOR_ID = "org.eclipse.wst.sse.ui"; //$NON-NLS-1$

	/**
	 * so we can tell if a partition changed after the last edit
	 */
	private String[] fLastPartitions;

	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#install(org.eclipse.jface.text.ITextViewer)
	 */
	public void install(ITextViewer textViewer) {

		super.install(textViewer);
		fTextInputListener = new SourceTextInputListener();
		textViewer.addTextInputListener(fTextInputListener);
	}
	
	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#uninstall()
	 */
	public void uninstall() {
		if (isInstalled()) {

			cancel();

			// removes document listeners
			reconcilerDocumentChanged(null);

			// removes widget listener
			getTextViewer().removeTextInputListener(fTextInputListener);

			IReconcilingStrategy validatorStrategy = getValidatorStrategy();
			
			if(validatorStrategy != null) {
				if(validatorStrategy instanceof IReleasable)
					((IReleasable)validatorStrategy).release();
			}
		}
		super.uninstall();
	}
	
	/**
	 * 
	 * @param oldInput
	 * @param newInput
	 */
	public void handleInputDocumentChanged(IDocument oldInput, IDocument newInput) {
		// don't bother if reconciler not installed
		if (isInstalled()) {

			reconcilerDocumentChanged(newInput);
			setDocument(newInput);
			setEntireDocumentDirty(newInput);
		}
	}
	
	public void setDocument(IDocument doc) {
		super.setDocument(doc);
		IReconcilingStrategy validatorStrategy = getValidatorStrategy();
		if(validatorStrategy != null) {
			validatorStrategy.setDocument(doc);
		}
	}
	
	/**
	 * Reinitializes listeners and sets new document onall strategies.
	 * 
	 * @see org.eclipse.jface.text.reconciler.AbstractReconciler#reconcilerDocumentChanged(IDocument)
	 */
	protected void reconcilerDocumentChanged(IDocument newDocument) {

		IDocument currentDoc = getDocument();

		// unhook old document listener
		if (currentDoc != null)
			currentDoc.removeDocumentListener(this);
		// hook up new document listener
		if (newDocument != null)
			newDocument.addDocumentListener(this);

		// sets document on all strategies
		super.reconcilerDocumentChanged(newDocument);
	}
	
	/**
	 * @param dirtyRegion
	 */
	protected void process(DirtyRegion dirtyRegion) {
		if (!isInstalled())
			return;

		ITypedRegion[] unfiltered = computePartitioning(dirtyRegion);

		// remove duplicate typed regions
		// that are handled by the same "total scope" strategy
		ITypedRegion[] filtered = filterTotalScopeRegions(unfiltered);

		DirtyRegion dirty = null;
		for (int i = 0; i < filtered.length; i++) {

			dirty = createDirtyRegion(filtered[i], DirtyRegion.INSERT);

			// validator (extension) for this partition
			if (getValidatorStrategy() != null)
				getValidatorStrategy().reconcile(filtered[i], dirty);
		}
	}
	/**
	 * Removes multiple "total-scope" regions (and leaves one) for a each
	 * partitionType. This improves performance by preventing unnecessary full
	 * document validations.
	 * 
	 * @param unfiltered
	 * @return
	 */
	protected ITypedRegion[] filterTotalScopeRegions(ITypedRegion[] unfiltered) {
		IReconcilingStrategy s = null;
		// ensure there is only one typed region in the list
		// for regions handled by "total scope" strategies
		HashMap totalScopeRegions = new HashMap();
		HashMap partialScopeRegions = new HashMap();
		List allRegions = new ArrayList();
		for (int i = 0; i < unfiltered.length; i++) {

			String partitionType = unfiltered[i].getType();

			// short circuit loop
			if (totalScopeRegions.containsKey(partitionType) || partialScopeRegions.containsKey(partitionType))
				continue;

			s = getReconcilingStrategy(partitionType);

			// might be the validator strategy
			if (s == null) {
				ValidatorStrategy validatorStrategy = getValidatorStrategy();
				if (validatorStrategy != null) {
					if (validatorStrategy.canValidatePartition(partitionType))
						s = validatorStrategy;
				}
			}

			if (s instanceof AbstractStructuredTextReconcilingStrategy) {
				// only allow one dirty region for a strategy
				// that has "total scope"
				if (((AbstractStructuredTextReconcilingStrategy) s).isTotalScope())
					totalScopeRegions.put(partitionType, unfiltered[i]);
				else
					partialScopeRegions.put(partitionType, unfiltered[i]);
			}
			else
				partialScopeRegions.put(partitionType, unfiltered[i]);
		}
		allRegions.addAll(totalScopeRegions.values());
		allRegions.addAll(partialScopeRegions.values());
		ITypedRegion[] filtered = (ITypedRegion[]) allRegions.toArray(new ITypedRegion[allRegions.size()]);

		if (DEBUG)
			System.out.println("filtered out this many 'total-scope' regions: " + (unfiltered.length - filtered.length)); //$NON-NLS-1$

		return filtered;
	}
	
	/**
	 * @return Returns the fValidatorStrategy.
	 */
	public ValidatorStrategy getValidatorStrategy() {
		if (fValidatorStrategy == null) {
			ValidatorStrategy validatorStrategy = null;
			
			if (getTextViewer() instanceof ISourceViewer) {
				ISourceViewer viewer = (ISourceViewer)getTextViewer();
				String contentTypeId = null;
				
				IDocument doc = viewer.getDocument();
				contentTypeId = getContentType(doc);
			
				if (contentTypeId != null) {
					
					validatorStrategy = new ValidatorStrategy(viewer, contentTypeId);
					ValidatorBuilder vBuilder = new ValidatorBuilder();
					ValidatorMetaData[] vmds = vBuilder.getValidatorMetaData(SSE_EDITOR_ID);
					for (int i = 0; i < vmds.length; i++) {
						if (vmds[i].canHandleContentType(contentTypeId))
							validatorStrategy.addValidatorMetaData(vmds[i]);
					}
				}
			}
			fValidatorStrategy = validatorStrategy;
		}
		return fValidatorStrategy;
	}

	protected String getContentType(IDocument doc) {
		
		if(doc == null)
			return null;
		
		String contentTypeId = null;
		
		// pa_TODO it would be nice to be able to get filename from IDocument...
		// because it seems that getting content type from input stream
		// isn't all that accurate (eg. w/ a javascript file)
		
		//IContentType ct = Platform.getContentTypeManager().findContentTypeFor("test.js");
		IContentType ct = null;
		try {
			IContentDescription desc = Platform.getContentTypeManager().getDescriptionFor(new ByteArrayInputStream(doc.get().getBytes()), null, IContentDescription.ALL);
			if(desc != null) {
				ct  = desc.getContentType();
				if(ct != null) 
					contentTypeId = ct.getId();
			}
		}
		catch (IOException e) {
			// just bail
		}
		return contentTypeId;
	}

	public void documentAboutToBeChanged(DocumentEvent event) {
		// save partition type (to see if it changes in documentChanged())
		fLastPartitions = getPartitions(event.getOffset(), event.getLength());			
	}

	public void documentChanged(DocumentEvent event) {
		if(partitionsChanged(event)) {
			// pa_TODO
			// this is a simple way to ensure old
			// annotations are removed when partition changes
			
			// it might be a performance hit though
			setEntireDocumentDirty(getDocument());
		}
		else {
			DirtyRegion dr = null;
			if(event.getLength() == 0) {
				// it's an insert
				// we use text length though
				// so that the new region gets validated...
				dr = createDirtyRegion(event.getOffset(), 0, DirtyRegion.INSERT);
			}
			else {
				if("".equals(event.getText())) { //$NON-NLS-1$
					// it's a delete
					dr =createDirtyRegion(event.getOffset(), event.getLength(), DirtyRegion.REMOVE);
				}
				else {
					// it's a replace
					dr = createDirtyRegion(event.getOffset(), event.getLength(), DirtyRegion.INSERT);	
				}
			}
			processDirtyRegion(dr);
		}
	}
	
	/**
	 * Checks previous partitions from the span of the event
	 * w/ the new partitions from the span of the event.
	 * If partitions changed, return true, else return false
	 * 
	 * @param event
	 * @return
	 */
	private boolean partitionsChanged(DocumentEvent event) {
		boolean changed = false;
		String[] newPartitions = getPartitions(event.getOffset(), event.getLength());
		if(fLastPartitions != null) {
			if(fLastPartitions.length != newPartitions.length) {
				changed = true;
			}
			else {
				for(int i=0; i<fLastPartitions.length; i++) {
					if(!fLastPartitions[i].equals(newPartitions[i])) {
						changed = true;
						break;
					}
				}	
			}
		}
		return changed;
	}
	
	/**
	 * Basically means process the entire document.
	 * @param document
	 */
	protected void setEntireDocumentDirty(IDocument document) {

		// make the entire document dirty
		// this also happens on a "save as"
		if (document != null && isInstalled()) {

			// since we're marking the entire doc dirty
			getDirtyRegionQueue().clear();
			DirtyRegion entireDocument = createDirtyRegion(0, document.getLength(), DirtyRegion.INSERT);
			processDirtyRegion(entireDocument);
		}
	}
}
