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

import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.reconciler.AbstractReconcileStep;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcilableModel;
import org.eclipse.jface.text.reconciler.IReconcileResult;
import org.eclipse.jface.text.reconciler.IReconcileStep;
import org.eclipse.wst.sse.core.IModelManager;
import org.eclipse.wst.sse.core.IStructuredModel;
import org.eclipse.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.rules.StructuredTextPartitioner;
import org.eclipse.wst.sse.ui.IReleasable;


/**
 * ReconcileStep that knows about the annotation that it adds to the
 * AnnotationModel. It knows how to create an annotation key (for smart
 * removal later) It knows the partition types on which it can operate. It
 * knows the scope on which it operates (for short circuiting) It knows if the
 * Reconciler is reconciling the entire document.
 * 
 * Clients must subclass this class.
 * 
 * @author pavery
 */
public abstract class StructuredReconcileStep extends AbstractReconcileStep implements IStructuredReconcileStep, IReleasable {
	public static final int ANNOTATION_LENGTH_LIMIT = 100;

	// these limits are safetys for "runaway" validation cases
	// should be used to safeguard potentially dangerous loops or potentially
	// long annotations
	// (since the painter seems to affect performance when painting long
	// annotations)
	public static final int ELEMENT_ERROR_LIMIT = 100;

	protected final IReconcileResult[] EMPTY_RECONCILE_RESULT_SET = new IReconcileResult[0];

	/**
	 * Flag so that TOTAL scope steps are only called once during a batch
	 * reconcile. reset() should be called after the batch reconcile.
	 */
	private boolean fAlreadyRanGlobalReconcile = false;
	private IModelManager fModelManager = null;
	private IStructuredReconcileStep fNextStructuredStep = null;
	/**
	 * It's possible for a partial step to get called on the same area twice
	 * (as w/ a full document reconcile) this list keeps track of area already
	 * covered. Should be reset() after the "batch" of reconciling is
	 * finished.
	 */
	private List fPartialRangesCovered = null;
	private HashSet fPartitionTypes = null;

	public StructuredReconcileStep() {
		super();
		fPartitionTypes = new HashSet();
		fPartialRangesCovered = new ArrayList();
	}

	public StructuredReconcileStep(IReconcileStep step) {
		super(step);
		if (step instanceof IStructuredReconcileStep)
			fNextStructuredStep = (IStructuredReconcileStep) step;

		fPartitionTypes = new HashSet();
		fPartialRangesCovered = new ArrayList();
	}

	public IReconcileAnnotationKey createKey(IStructuredDocumentRegion sdRegion, int scope) {
		ITypedRegion tr = sdRegion.getParentDocument().getDocumentPartitioner().getPartition(sdRegion.getStartOffset());
		String partitionType = (tr != null) ? tr.getType() : StructuredTextPartitioner.ST_UNKNOWN_PARTITION;
		return createKey(partitionType, scope);
	}

	/**
	 * Clients should use this method to create annotation keys as it
	 * registers the key for removal later.
	 * 
	 * @param partitionType
	 * @param scope
	 * @return
	 */
	public IReconcileAnnotationKey createKey(String partitionType, int scope) {
		fPartitionTypes.add(partitionType);
		return new ReconcileAnnotationKey(this, partitionType, scope);
	}

	protected IDocument getDocument() {
		IDocument doc = null;
		IReconcilableModel rModel = getModel();
		if (rModel instanceof DocumentAdapter) {
			doc = ((DocumentAdapter) rModel).getDocument();
		}
		return doc;
	}

	/*
	 * @see org.eclipse.text.reconcilerpipe.AbstractReconcilePipeParticipant#getModel()
	 */
	public IReconcilableModel getModel() {
		return getInputModel();
	}

	/**
	 * Avoid excessive calls to Platform.getPlugin(ModelPlugin.ID)
	 * 
	 * @return sse model manager
	 */
	protected IModelManager getModelManager() {
		if (fModelManager == null)
			fModelManager = StructuredModelManager.getInstance().getModelManager();
		return fModelManager;
	}

	protected IDocumentPartitioner getPartitioner() {
		return getDocument().getDocumentPartitioner();
	}

	public String getPartitionType(int offset) {
		ITypedRegion tr = getPartitioner().getPartition(offset);
		return (tr != null) ? tr.getType() : StructuredTextPartitioner.ST_UNKNOWN_PARTITION;
	}

	public String[] getPartitionTypes() {
		// using hash set to automatically get rid of dupes
		HashSet tempResults = new HashSet();
		// add these partition types
		tempResults.addAll(fPartitionTypes);
		// add next step's partition types
		if (fNextStructuredStep != null) {
			String[] nextResults = fNextStructuredStep.getPartitionTypes();
			for (int i = 0; i < nextResults.length; i++)
				tempResults.add(nextResults[i]);
		}
		return (String[]) tempResults.toArray(new String[tempResults.size()]);
	}

	public abstract int getScope();

	protected IStructuredDocument getStructuredDocument() {
		IStructuredDocument sDoc = null;
		IDocument doc = getDocument();
		if (doc instanceof IStructuredDocument)
			sDoc = (IStructuredDocument) getDocument();
		return sDoc;
	}

	/**
	 * @param dirtyRegion
	 * @return
	 */
	private boolean isInPartiallyCheckedRanges(DirtyRegion dirtyRegion) {
		// pa_TODO reconciler performance, this can be bad
		Iterator it = fPartialRangesCovered.iterator();
		Position p = null;
		while (it.hasNext()) {
			p = (Position) it.next();
			if (p.overlapsWith(dirtyRegion.getOffset(), dirtyRegion.getLength()))
				return true;
		}

		// add new range that has been covered
		IStructuredModel sm = getModelManager().getExistingModelForRead(getDocument());
		IndexedRegion indexed = sm.getIndexedRegion(dirtyRegion.getOffset());
		sm.releaseFromRead();
		if (indexed != null)
			fPartialRangesCovered.add(new Position(indexed.getStartOffset(), indexed.getEndOffset() - indexed.getStartOffset()));
		return false;
	}

	/**
	 * If step passed in is found somewhere in the chain of steps.
	 * 
	 * @return true if step passed in is found somewhere in the chain of
	 *         steps, else false
	 */
	public boolean isSiblingStep(IReconcileStep step) {
		if (step == null)
			return false;
		else if (step.equals(this))
			return true;
		else if (isLastStep())
			return false;
		else
			return fNextStructuredStep.isSiblingStep(step);
	}

	/**
	 * Removes duplicates.
	 * 
	 * @param results1
	 * @param results2
	 * @return
	 */
	protected IReconcileResult[] merge(IReconcileResult[] results1, IReconcileResult[] results2) {
		if (results1 == null)
			return results2;
		if (results2 == null)
			return results1;

		List results = new ArrayList();
		results.addAll(Arrays.asList(results1));
		for (int i = 0; i < results2.length; i++) {
			// pa_TODO: could be bad for performance
			if (!results.contains(results2[i]))
				results.add(results2[i]);
		}

		return (IReconcileResult[]) results.toArray(new IReconcileResult[results.size()]);
	}

	/**
	 * Like IReconcileStep.reconcile() except takes into consideration if the
	 * strategy may be called multiple times in this same "run" (ie. a
	 * processAll() call from the StructuredTextReconciler)
	 */
	public final IReconcileResult[] reconcile(DirtyRegion dirtyRegion, IRegion subRegion, boolean refreshAll) {
		IReconcileResult[] result = EMPTY_RECONCILE_RESULT_SET;

		if (!refreshAll) {
			result = reconcileModel(dirtyRegion, subRegion);
			fAlreadyRanGlobalReconcile = false;
		} else if (getScope() == IReconcileAnnotationKey.TOTAL && !fAlreadyRanGlobalReconcile) {
			result = reconcileModel(dirtyRegion, subRegion);
			fAlreadyRanGlobalReconcile = true;
		} else if (getScope() == IReconcileAnnotationKey.PARTIAL) {
			if (!isInPartiallyCheckedRanges(dirtyRegion)) {
				result = reconcileModel(dirtyRegion, subRegion);
			}
		}

		if (!isLastStep()) {
			((IReconcileStep) fNextStructuredStep).setInputModel(getModel());
			IReconcileResult[] nextResult = fNextStructuredStep.reconcile(dirtyRegion, subRegion, refreshAll);
			return merge(result, convertToInputModel(nextResult));
		}
		return result;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.text.reconciler.AbstractReconcileStep#reconcileModel(org.eclipse.jface.text.reconciler.DirtyRegion,
	 *      org.eclipse.jface.text.IRegion)
	 */
	protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion, IRegion subRegion) {
		return EMPTY_RECONCILE_RESULT_SET;
	}

	/**
	 * Release resources used by the step here as needed. Be sure to call
	 * super.release() when you override this method as to propagate the
	 * release through all steps.
	 */
	public void release() {
		if (fNextStructuredStep != null && fNextStructuredStep instanceof IReleasable)
			((IReleasable) fNextStructuredStep).release();
		// we don't to null out the steps, in case
		// it's reconfigured later
		//fNextStructuredStep = null;
		fModelManager = null;
	}

	public void reset() {
		fAlreadyRanGlobalReconcile = false;
		fPartialRangesCovered.clear();

		if (!isLastStep())
			fNextStructuredStep.reset();
	}
}
