/*******************************************************************************
 * Copyright (c) 2006, 2009 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.wst.sse.ui.internal.reconcile;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
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.core.runtime.content.IContentTypeManager;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
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.ExtendedConfigurationBuilder;
import org.eclipse.wst.sse.ui.internal.IReleasable;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
import org.eclipse.wst.sse.ui.internal.projection.AbstractStructuredFoldingStrategy;
import org.eclipse.wst.sse.ui.internal.provisional.preferences.CommonEditorPreferenceNames;
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;
import org.eclipse.wst.sse.ui.internal.spelling.SpellcheckStrategy;

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

	private static final boolean DEBUG_VALIDATORS = Boolean.TRUE.toString().equalsIgnoreCase(Platform.getDebugOption("org.eclipse.wst.sse.ui/debug/reconcilerValidators")); //$NON-NLS-1$

	/**
	 * A strategy to use the defined default Spelling service.
	 */
	private IReconcilingStrategy fSpellcheckStrategy;

	/**
	 * The strategy that runs validators contributed via
	 * <code>org.eclipse.wst.sse.ui.extensions.sourcevalidation</code>
	 * extension point
	 */
	private ValidatorStrategy fValidatorStrategy;

	private IReconcilingStrategy fSemanticHighlightingStrategy;
	
	/**
	 * The folding strategy for this processor
	 */
	private AbstractStructuredFoldingStrategy fFoldingStrategy;
	
	private final String SSE_UI_ID = "org.eclipse.wst.sse.ui"; //$NON-NLS-1$

	/**
	 * true if as you type validation is enabled,
	 * false otherwise
	 */
	private boolean fValidationEnabled;
	
	protected void beginProcessing() {
		super.beginProcessing();
		ValidatorStrategy validatorStrategy = getValidatorStrategy();
		if (validatorStrategy != null) {
			validatorStrategy.beginProcessing();
		}
	}

	protected void endProcessing() {
		super.endProcessing();
		ValidatorStrategy validatorStrategy = getValidatorStrategy();
		if (validatorStrategy != null) {
			validatorStrategy.endProcessing();
		}
		/* single spell-check for everything to ensure that SpellingProblem offsets are correct */
		IReconcilingStrategy spellingStrategy = getSpellcheckStrategy();
		IDocument document = getDocument();
		if (spellingStrategy != null && document != null) {
			getSpellcheckStrategy().reconcile(new Region(0, document.getLength()));
		}
		
		IReconcilingStrategy semanticHighlightingStrategy = getSemanticHighlightingStrategy();
		if (semanticHighlightingStrategy != null && document != null) {
			semanticHighlightingStrategy.reconcile(new Region(0, document.getLength()));
		}
	}

	protected String getContentType(IDocument doc) {
		if (doc == null)
			return null;

		String contentTypeId = null;

		IContentType ct = null;
		try {
			IContentDescription desc = Platform.getContentTypeManager().getDescriptionFor(new StringReader(doc.get()), null, IContentDescription.ALL);
			if (desc != null) {
				ct = desc.getContentType();
				if (ct != null)
					contentTypeId = ct.getId();
			}
		}
		catch (IOException e) {
			// just bail
		}
		return contentTypeId;
	}

	protected IReconcilingStrategy getSpellcheckStrategy() {
		if (fSpellcheckStrategy == null && getDocument() != null) {
			String contentTypeId = getContentType(getDocument());
			if (contentTypeId == null) {
				contentTypeId = IContentTypeManager.CT_TEXT;
			}
			if (getTextViewer() instanceof ISourceViewer) {
				ISourceViewer viewer = (ISourceViewer) getTextViewer();
				fSpellcheckStrategy = new SpellcheckStrategy(viewer, contentTypeId);
				fSpellcheckStrategy.setDocument(getDocument());
			}
		}
		return fSpellcheckStrategy;
	}
	
	/**
	 * <p>Get the folding strategy for this processor. Retrieved from the 
	 * extended configuration builder.  The processor chosen is set by the plugin.</p>
	 * 
	 * <p>EX:<br />
	 * <code>&lt;extension point="org.eclipse.wst.sse.ui.editorConfiguration"&gt;<br />
	 *  &lt;provisionalConfiguration<br />
	 *			type="foldingstrategy"<br />
	 *			class="org.eclipse.wst.xml.ui.internal.projection.XMLFoldingStrategy"<br />
	 *			target="org.eclipse.core.runtime.xml, org.eclipse.wst.xml.core.xmlsource" /&gt;<br />
	 *	&lt;/extension&gt;</code></p>
	 * 
	 * <p>The type must be equal to <code>AbstractFoldingStrategy.ID</code> (AKA: foldingstrategy)
	 * and the class must extend <code>org.eclipse.wst.sse.ui.internal.projection.AbstractFoldingStrategy</code>
	 * and the target must be a structured editor content type ID</p>
	 * 
	 * @return the requested folding strategy or null if none can be found
	 */
	protected IReconcilingStrategy getFoldingStrategy() {
		if(fFoldingStrategy == null && getDocument() != null) {
			String contentTypeId = getContentType(getDocument());
			if (contentTypeId == null) {
				contentTypeId = IContentTypeManager.CT_TEXT;
			}
			
			ITextViewer viewer = getTextViewer();
			if(viewer instanceof StructuredTextViewer) {
				ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
				
				IContentType type = Platform.getContentTypeManager().getContentType(contentTypeId);
				while(fFoldingStrategy == null && type != null) {
					fFoldingStrategy =(AbstractStructuredFoldingStrategy) builder.getConfiguration(
							AbstractStructuredFoldingStrategy.ID, type.getId());
				
					type = type.getBaseType();
				}
				
				if(fFoldingStrategy != null) {
					fFoldingStrategy.setViewer((StructuredTextViewer)viewer);
					fFoldingStrategy.setDocument(getDocument());
				}
			}
		}
		
		return fFoldingStrategy;
	}
	
	/**
	 * Enable or disable as you type validation. Typically set by a user preference
	 * 
	 * @param enable true to enable as you type validation, false to disable
	 */
	public void setValidatorStrategyEnabled(boolean enable) {
		fValidationEnabled = enable;
	}

	/**
	 * @return Returns the ValidatorStrategy.
	 */
	protected ValidatorStrategy getValidatorStrategy() {
		ValidatorStrategy validatorStrategy = null;
		if (fValidatorStrategy == null && fValidationEnabled) {
			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_UI_ID);
					List enabledValidators = new ArrayList(1);
					/* if any "must" handle this content type, just add them */
					boolean foundSpecificContentTypeValidators = false;
					for (int i = 0; i < vmds.length; i++) {
						if (vmds[i].mustHandleContentType(contentTypeId)) {
							if (DEBUG_VALIDATORS)
								Logger.log(Logger.INFO, contentTypeId + " using specific validator " + vmds[i].getValidatorId()); //$NON-NLS-1$
							foundSpecificContentTypeValidators = true;
							enabledValidators.add(vmds[i]);
						}
					}
					if (!foundSpecificContentTypeValidators) {
						for (int i = 0; i < vmds.length; i++) {
							if (vmds[i].canHandleContentType(contentTypeId)) {
								if (DEBUG_VALIDATORS)
									Logger.log(Logger.INFO, contentTypeId + " using inherited(?) validator " + vmds[i].getValidatorId()); //$NON-NLS-1$
								enabledValidators.add(vmds[i]);
							}
						}
					}
					for (int i = 0; i < enabledValidators.size(); i++) {
						validatorStrategy.addValidatorMetaData((ValidatorMetaData) enabledValidators.get(i));
					}
				}
			}
			fValidatorStrategy = validatorStrategy;
		} else if(fValidatorStrategy != null && fValidationEnabled) {
			validatorStrategy = fValidatorStrategy;
		}
		return validatorStrategy;
	}
	
	public void setSemanticHighlightingStrategy(IReconcilingStrategy semanticHighlightingStrategy) {
		fSemanticHighlightingStrategy = semanticHighlightingStrategy;
		fSemanticHighlightingStrategy.setDocument(getDocument());
	}
	
	protected IReconcilingStrategy getSemanticHighlightingStrategy() {
		return fSemanticHighlightingStrategy;
	}
	
	/**
	 * @param dirtyRegion
	 */
	protected void process(DirtyRegion dirtyRegion) {
		if (!isInstalled() || isInRewriteSession())
			return;

		super.process(dirtyRegion);
		
		ITypedRegion[] partitions = computePartitioning(dirtyRegion);
		
		// call the validator strategy once for each effected partition
		DirtyRegion dirty = null;
		for (int i = 0; i < partitions.length; i++) {
			dirty = createDirtyRegion(partitions[i], DirtyRegion.INSERT);

			// [source]validator (extension) for this partition
			if (getValidatorStrategy() != null) {
				getValidatorStrategy().reconcile(partitions[i], dirty);
			}
		}
		
		/* if there is a folding strategy then reconcile it for the
		 * entire dirty region.
		 * NOTE: the folding strategy does not care about the sub regions.
		 */
		if(getFoldingStrategy() != null) {
			getFoldingStrategy().reconcile(dirtyRegion, null);
		}
	}

	public void setDocument(IDocument doc) {
		super.setDocument(doc);
		
		IReconcilingStrategy validatorStrategy = getValidatorStrategy();
		if (validatorStrategy != null) {
			validatorStrategy.setDocument(doc);
		}
		
		fSpellcheckStrategy = null;
		if(fFoldingStrategy != null) {
			fFoldingStrategy.uninstall();
		}
		fFoldingStrategy = null;
	}

	protected void setEntireDocumentDirty(IDocument document) {
		super.setEntireDocumentDirty(document);

		// make the entire document dirty
		// this also happens on a "save as"
		if (document != null && isInstalled() && fLastPartitions != null && document.getLength() == 0) {
			/**
			 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=199053
			 * 
			 * Process the strategies for the last known-good partitions.
			 */
			for (int i = 0; i < fLastPartitions.length; i++) {
				ValidatorStrategy validatorStrategy = getValidatorStrategy();
				if (validatorStrategy != null) {
					validatorStrategy.reconcile(fLastPartitions[i], createDirtyRegion(fLastPartitions[i], DirtyRegion.REMOVE));
				}
			}
			IReconcilingStrategy spellingStrategy = getSpellcheckStrategy();
			if (spellingStrategy != null) {
				spellingStrategy.reconcile(new Region(0, document.getLength()));
			}
			
			//if there is a folding strategy then reconcile it
			if(getFoldingStrategy() != null) {
				getFoldingStrategy().reconcile(new Region(0, document.getLength()));
			}
		}
	}

	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#install(org.eclipse.jface.text.ITextViewer)
	 */
	public void install(ITextViewer textViewer) {
		super.install(textViewer);
		
		//determine if validation is enabled
		this.fValidationEnabled = SSEUIPlugin.getInstance().getPreferenceStore().getBoolean(
				CommonEditorPreferenceNames.EVALUATE_TEMPORARY_PROBLEMS);
	}
	
	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.DirtyRegionProcessor#uninstall()
	 */
	public void uninstall() {
		if (isInstalled()) {

			cancel();

			IReconcilingStrategy validatorStrategy = getValidatorStrategy();

			if (validatorStrategy != null) {
				if (validatorStrategy instanceof IReleasable)
					((IReleasable) validatorStrategy).release();
			}
			
			if (fSpellcheckStrategy != null) {
				fSpellcheckStrategy.setDocument(null);
				fSpellcheckStrategy = null;
			}
		}
		super.uninstall();
	}
}
