/*******************************************************************************
 * Copyright (c) 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
 *******************************************************************************/
package org.eclipse.jst.jsp.ui.internal.reconcile;

import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.Position;
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.jst.jsp.core.internal.java.JSPTranslation;
import org.eclipse.jst.jsp.core.internal.java.JSPTranslationExtension;
import org.eclipse.jst.jsp.core.internal.text.rules.StructuredTextPartitionerForJSP;
import org.eclipse.wst.sse.core.IStructuredModel;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.ui.internal.reconcile.ReconcileAnnotationKey;
import org.eclipse.wst.sse.ui.internal.reconcile.StructuredReconcileStep;
import org.eclipse.wst.sse.ui.internal.reconcile.TemporaryAnnotation;

/**
 * This reconcile step has a Java source document as input model and maintains
 * a Java working copy as its model.
 * 
 * @since 3.0
 */
public class ReconcileStepForJava extends StructuredReconcileStep {

	/**
	 * Adapts an <code>ICompilationUnit</code> to the
	 * <code>ITextModel</code> interface.
	 */
	private class CompilationUnitAdapter implements IReconcilableModel {

		private ICompilationUnit fCompilationUnit;

		CompilationUnitAdapter(ICompilationUnit cu) {
			fCompilationUnit = cu;
		}

		private ICompilationUnit getCompilationUnit() {
			return fCompilationUnit;
		}
	}

	private JSPTranslation fJspTranslation;
	private CompilationUnitAdapter fModel;
	private IStructuredDocument fStructuredDocument = null;

	/**
	 * Creates the last reconcile step of the pipe.
	 */
	public ReconcileStepForJava(IFile jspFile) {
		// should handle more gracefully
		Assert.isNotNull(jspFile);
		initStructuredDocument(jspFile);
	}

	/**
	 * Creates an intermediate reconcile step which adds the given step to the
	 * pipe.
	 */
	public ReconcileStepForJava(IReconcileStep step, IFile jspFile) {
		super(step);
		Assert.isNotNull(jspFile);
		initStructuredDocument(jspFile);
	}

	/**
	 * Structured Document used to create annotation removal keys
	 * 
	 * @param jspFile
	 */
	private void initStructuredDocument(IFile jspFile) {
		IStructuredModel sModel = null;
		try {
			sModel = StructuredModelManager.getModelManager().getExistingModelForRead(jspFile);
			if (sModel != null)
				fStructuredDocument = sModel.getStructuredDocument();
		}
		finally {
			if (sModel != null)
				sModel.releaseFromRead();
		}
	}

	/*
	 * @see AbstractReconcileStep#reconcileModel(DirtyRegion, IRegion)
	 */
	protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion, IRegion subRegion) {
		Assert.isTrue(getInputModel() instanceof JSPTranslationWrapper, "wrong model"); //$NON-NLS-1$
		fJspTranslation = ((JSPTranslationWrapper) getInputModel()).getTranslation();
		
        if(DEBUG)
            System.out.println("[trace reconciler] > reconciling model in JAVA step w/ dirty region: " + dirtyRegion.getText()); //$NON-NLS-1$

		try {
			fJspTranslation.setProblemCollectingActive(true);
			fJspTranslation.reconcileCompilationUnit();
		}
		finally {
			if (fJspTranslation != null)
				fJspTranslation.setProblemCollectingActive(false);
		}

		List problems = null;
		// I was frequently seeing null here, especially as editors closed, 
		// so just gaurding against that. (Not sure why it was null). 
		if (fJspTranslation != null) {
			problems = fJspTranslation.getProblems();
		}
		IReconcileResult[] results = adaptProblemsToAnnotations(problems);
		return results;
	}

	/**
	 * @return
	 */
	private IReconcileResult[] adaptProblemsToAnnotations(List problems) {
		if (problems == null)
			return new IReconcileResult[0];

		TemporaryAnnotation[] annotations = new TemporaryAnnotation[problems.size()];
		IProblem p = null;
		for (int i = 0; i < problems.size(); i++) {
			p = (IProblem) problems.get(i);
			annotations[i] = createTemporaryAnnotationFromProblem(p);
		}
		return annotations;
	}

	/**
	 * Converts an IProblem to a TemporaryAnnotation.
	 * 
	 * @param problem
	 * @return
	 */
	private TemporaryAnnotation createTemporaryAnnotationFromProblem(IProblem problem) {
		String type = TemporaryAnnotation.ANNOT_ERROR;
		if (problem.isWarning())
			type = TemporaryAnnotation.ANNOT_WARNING;
		Position pos = new Position(problem.getSourceStart(), problem.getSourceEnd() - problem.getSourceStart() + 1);
		JSPTranslationExtension translation = ((JSPTranslationWrapper) getInputModel()).getTranslation();
		int jspOffset = translation.getJspOffset(pos.offset);

		ReconcileAnnotationKey key = null;
		if (jspOffset != -1 && fStructuredDocument != null) {
			key = createKey(fStructuredDocument.getRegionAtCharacterOffset(jspOffset), ReconcileAnnotationKey.TOTAL);
		}
		else {
			key = createKey(StructuredTextPartitionerForJSP.ST_DEFAULT_JSP, ReconcileAnnotationKey.TOTAL);
		}
		TemporaryAnnotation annotation = new TemporaryAnnotation(pos, type, problem.getMessage(), key, problem.getID());
		annotation.setAdditionalFixInfo(problem);

		return annotation;
	}

	/*
	 * @see AbstractReconcileStep#getModel()
	 */
	public IReconcilableModel getModel() {
		if (fModel == null) {
			fModel = new CompilationUnitAdapter(fJspTranslation.getCompilationUnit());
		}
		return fModel;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jface.text.reconciler.IReconcileStep#setInputModel(org.eclipse.jface.text.reconciler.IReconcilableModel)
	 */
	public void setInputModel(IReconcilableModel inputModel) {
		super.setInputModel(inputModel);
	}
}