/*******************************************************************************
 * 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.validator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.runtime.Platform;
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.ITypedRegion;
import org.eclipse.jface.text.reconciler.DirtyRegion;
import org.eclipse.jface.text.reconciler.IReconcileResult;
import org.eclipse.jface.text.reconciler.IReconcileStep;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.wst.sse.ui.internal.IReleasable;
import org.eclipse.wst.sse.ui.internal.reconcile.DocumentAdapter;
import org.eclipse.wst.sse.ui.internal.reconcile.ReconcileAnnotationKey;
import org.eclipse.wst.sse.ui.internal.reconcile.StructuredTextReconcilingStrategy;
import org.eclipse.wst.sse.ui.internal.reconcile.TemporaryAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IValidator;


/**
 * Special validator strategy. Runs validator steps contributed via the
 * <code>org.eclipse.wst.sse.ui.extensions.sourcevalidation</code> extension
 * point
 * 
 * @author pavery
 */
public class ValidatorStrategy extends StructuredTextReconcilingStrategy {

	private String[] fContentTypeIds = null;
	private List fMetaData = null;
	/** validator id (as declared in ext point) -> ReconcileStepForValidator * */
	private HashMap fVidToVStepMap = null;

	/*
	 * List of ValidatorMetaDatas of total scope validators that have been run
	 * since beginProcessing() was called.
	 */
	private List fTotalScopeValidatorsAlreadyRun;

	public ValidatorStrategy(ISourceViewer sourceViewer, String contentType) {
		super(sourceViewer);
		fMetaData = new ArrayList();
		fContentTypeIds = calculateParentContentTypeIds(contentType);
		fVidToVStepMap = new HashMap();
	}

	public void addValidatorMetaData(ValidatorMetaData vmd) {
		fMetaData.add(vmd);
	}

	public void beginProcessing() {
		if (fTotalScopeValidatorsAlreadyRun == null)
			fTotalScopeValidatorsAlreadyRun = new ArrayList();
	}

	/**
	 * The content type passed in should be the most specific one. TODO: This
	 * exact method is also in ValidatorMetaData. Should be in a common place.
	 * 
	 * @param contentType
	 * @return
	 */
	private String[] calculateParentContentTypeIds(String contentTypeId) {

		Set parentTypes = new HashSet();

		IContentTypeManager ctManager = Platform.getContentTypeManager();
		IContentType ct = ctManager.getContentType(contentTypeId);
		String id = contentTypeId;

		while (ct != null && id != null) {

			parentTypes.add(id);
			ct = ctManager.getContentType(id);
			if (ct != null) {
				IContentType baseType = ct.getBaseType();
				id = (baseType != null) ? baseType.getId() : null;
			}
		}
		return (String[]) parentTypes.toArray(new String[parentTypes.size()]);
	}

	protected boolean canHandlePartition(String partitionType) {
		ValidatorMetaData vmd = null;
		for (int i = 0; i < fMetaData.size(); i++) {
			vmd = (ValidatorMetaData) fMetaData.get(i);
			if (vmd.canHandlePartitionType(getContentTypeIds(), partitionType))
				return true;
		}
		return false;
	}

	protected boolean containsStep(IReconcileStep step) {
		return fVidToVStepMap.containsValue(step);
	}

	/**
	 * @see org.eclipse.wst.sse.ui.internal.provisional.reconcile.AbstractStructuredTextReconcilingStrategy#createReconcileSteps()
	 */
	public void createReconcileSteps() {
		// do nothing, steps are created
	}

	public void endProcessing() {
		fTotalScopeValidatorsAlreadyRun.clear();
	}

	/**
	 * All content types on which this ValidatorStrategy can run
	 * 
	 * @return
	 */
	public String[] getContentTypeIds() {
		return fContentTypeIds;
	}

	/**
	 * @param tr
	 *            Partition of the region to reconcile.
	 * @param dr
	 *            Dirty region representation of the typed region
	 */
	public void reconcile(ITypedRegion tr, DirtyRegion dr) {

		if (isCanceled())
			return;

		IDocument doc = getDocument();
		// for external files, this can be null
		if (doc == null)
			return;

		String partitionType = tr.getType();

		ValidatorMetaData vmd = null;
		List annotationsToAdd = new ArrayList();
		/*
		 * Loop through all of the relevant validator meta data to find
		 * supporting validators for this partition type. Don't check
		 * this.canHandlePartition() before-hand since it just loops through
		 * and calls vmd.canHandlePartitionType()...which we're already doing
		 * here anyway to find the right vmd.
		 */
		for (int i = 0; i < fMetaData.size() && !isCanceled(); i++) {
			vmd = (ValidatorMetaData) fMetaData.get(i);
			if (vmd.canHandlePartitionType(getContentTypeIds(), partitionType)) {
				int validatorScope = vmd.getValidatorScope();
				ReconcileStepForValidator validatorStep = null;
				// get step for partition type
				Object o = fVidToVStepMap.get(vmd.getValidatorId());
				if (o != null) {
					validatorStep = (ReconcileStepForValidator) o;
				}
				else {
					// if doesn't exist, create one
					IValidator validator = vmd.createValidator();

					validatorStep = new ReconcileStepForValidator(validator, validatorScope);
					validatorStep.setInputModel(new DocumentAdapter(doc));

					fVidToVStepMap.put(vmd.getValidatorId(), validatorStep);
				}

				if (!fTotalScopeValidatorsAlreadyRun.contains(vmd)) {
					annotationsToAdd.addAll(Arrays.asList(validatorStep.reconcile(dr, dr)));

					if (validatorScope == ReconcileAnnotationKey.TOTAL) {
						// mark this validator as "run"
						fTotalScopeValidatorsAlreadyRun.add(vmd);
					}
				}
			}
		}

		TemporaryAnnotation[] annotationsToRemove = getAnnotationsToRemove(dr);
		if (annotationsToRemove.length + annotationsToAdd.size() > 0)
			smartProcess(annotationsToRemove, (IReconcileResult[]) annotationsToAdd.toArray(new IReconcileResult[annotationsToAdd.size()]));
	}

	public void release() {
		super.release();
		Iterator it = fVidToVStepMap.values().iterator();
		IReconcileStep step = null;
		while (it.hasNext()) {
			step = (IReconcileStep) it.next();
			if (step instanceof IReleasable)
				((IReleasable) step).release();
		}
	}

	/**
	 * @see org.eclipse.wst.sse.ui.internal.reconcile.AbstractStructuredTextReconcilingStrategy#setDocument(org.eclipse.jface.text.IDocument)
	 */
	public void setDocument(IDocument document) {

		super.setDocument(document);

		// validator steps are in "fVIdToVStepMap" (as opposed to fFirstStep >
		// next step etc...)
		Iterator it = fVidToVStepMap.values().iterator();
		IReconcileStep step = null;
		while (it.hasNext()) {
			step = (IReconcileStep) it.next();
			step.setInputModel(new DocumentAdapter(document));
		}
	}
}
