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

		// Also call the validation and spell-check strategies
		ITypedRegion[] partitions = computePartitioning(dirtyRegion);

		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
			if(getFoldingStrategy() != null) {
				getFoldingStrategy().reconcile(dirty, partitions[i]);
			}
		}
	}

	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();
	}
}
