/*******************************************************************************
 * Copyright (c) 2009 by SAP AG, Walldorf. 
 * 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:
 *     SAP AG - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.jaxws.utils.internal.annotations.impl;

import java.io.FileNotFoundException;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeParameter;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jst.ws.jaxws.utils.annotations.AnnotationGeneratorException;
import org.eclipse.jst.ws.jaxws.utils.clazz.ASTUtils;
import org.eclipse.jst.ws.jaxws.utils.internal.text.JaxWsUtilMessages;
import org.eclipse.jst.ws.jaxws.utils.resources.EditResourcesManager;
import org.eclipse.jst.ws.jaxws.utils.resources.FileUtils;
import org.eclipse.jst.ws.jaxws.utils.resources.IFileUtils;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;

/**
 * Contains utilities for getting AST objects needed in annotation processing
 * 
 * @author Plamen Pavlov
 */
public class AnnotationUtils
{
	private static AnnotationUtils utils = null;
	private final IFileUtils fileUtils = FileUtils.getInstance();

	/**
	 * The factory method.
	 * 
	 * @return a AnnotationUtils instance.
	 */
	public static AnnotationUtils getInstance()
	{
		if (utils == null)
		{
			utils = new AnnotationUtils();
		}
		return utils;
	}
	
	/**
	 * Gets IDocument, which coresponds to one CompilationUnit.
	 * 
	 * @param unit -
	 *            Compilation Unit, which will be used as starting point to get the IDocument.
	 * 
	 * @return IDocument which is found.
	 * 
	 * @throws CoreException
	 */
	public IDocument getDocument(ICompilationUnit unit) throws CoreException
	{
		String source = unit.getBuffer().getContents(); 
		return new Document(source); 
	}
	
	/**
	 * Removes Annotations of specified IJavaElement.
	 * 
	 * @param javaElement - IJavaElement which will be used as starting poin for removing the annotations.
	 * @param annotations - Set which contains String values for the annotations which will be removed. If this Set is empty all Annotations will be removed.
	 * @param deepRemove - Boolean value, representing whether Annotations from javaElemet childs will be removed. 
	 * @throws AnnotationGeneratorException 
	 * 
	 * @throws AnnotationGeneratorException
	 *             thown if AST TypeDeclaration cannot be found for <code>type</code> and also is used as wrapper in case {@link CoreException} or
	 *             {@link BadLocationException} is thrown while processing.
	 * @throws BadLocationException 
	 * @throws CoreException 
	 * @throws FileNotFoundException 
	 * @throws MalformedTreeException 
	 */
	public void removeAnnotations(IJavaElement javaElement, Set<String> annotations, boolean deepRemove) throws AnnotationGeneratorException, MalformedTreeException, FileNotFoundException, CoreException, BadLocationException
	{
		if(javaElement instanceof IType)
		{
			IType type = (IType)javaElement;
			ICompilationUnit cUnit = type.getCompilationUnit();
			String className = type.getElementName();
			CompilationUnit unit = ASTUtils.getInstance().createCompilationUnit(cUnit, null);

			AbstractTypeDeclaration typeDeclaration = ASTUtils.getInstance().getTypeDeclaration(className, unit);
			if (typeDeclaration == null)
			{
				throw new AnnotationGeneratorException("typeDeclaration should not be null",//$NON-NLS-1$
							MessageFormat.format(JaxWsUtilMessages.AnnotationUtils_ParamShouldNotBeNullMsg, "typeDeclaration")); //$NON-NLS-1$
			}
			
			removeTypeAnnotations(type, typeDeclaration, unit, cUnit, annotations);

			if(!deepRemove)
			{
				return;
			}
			
			IField[] tmpFields = type.getFields();
			if (tmpFields != null && tmpFields.length > 0)
			{
				for (IField tmpField : tmpFields)
				{
					removeFieldAnnotations(tmpField, type, cUnit, annotations);
				}
			}
			
			IMethod[] tmpMethods = type.getMethods();
			if (tmpMethods != null && tmpMethods.length > 0)
			{
				for (IMethod tmpMethod : tmpMethods)
				{
					removeMethodAnnotations(tmpMethod, type, cUnit, annotations);

					//Remove params annotations
					for (String paramName : tmpMethod.getParameterNames())
					{
						ITypeParameter typeParameter = tmpMethod.getTypeParameter(paramName);
						removeParamAnnotations(typeParameter, type, cUnit, annotations, paramName);			
					}
				}
			}
		}
		
		if(javaElement instanceof IField)
		{
			IField field = (IField)javaElement;
			IType declaringType = field.getDeclaringType();
			ICompilationUnit declaringTypeCompUnit = declaringType.getCompilationUnit();
			
			removeFieldAnnotations(field, declaringType, declaringTypeCompUnit, annotations);
		}
		
		if(javaElement instanceof IMethod)
		{
			IMethod method = (IMethod)javaElement;
			IType declaringType = method.getDeclaringType();
			ICompilationUnit declaringTypeCompUnit = declaringType.getCompilationUnit();
			
			removeMethodAnnotations(method, declaringType, declaringTypeCompUnit, annotations);
			if(!deepRemove)
			{
				return;
			}

			//Remove params annotations
			for (String paramName: method.getParameterNames())
			{
			  ITypeParameter param = method.getTypeParameter(paramName);
			  removeParamAnnotations(param, declaringType, declaringTypeCompUnit, annotations, paramName);
			}
		}
		
		if(javaElement instanceof ITypeParameter)
		{
			ITypeParameter typeParameter = (ITypeParameter)javaElement;
			IMethod tmpMethod = (IMethod) typeParameter.getDeclaringMember();
			//TODO check this
			//param.getParent();
			IType declaringType = tmpMethod.getDeclaringType();
			ICompilationUnit declaringTypeCompUnit = declaringType.getCompilationUnit();
			//TODO FIX THIS
			removeParamAnnotations(typeParameter, declaringType, declaringTypeCompUnit, annotations, null);
		}
	}
	
	private void removeTypeAnnotations(IType type, AbstractTypeDeclaration typeDeclaration, CompilationUnit unit, ICompilationUnit cUnit, Set<String> annotationsSet) throws CoreException, MalformedTreeException, BadLocationException, FileNotFoundException, AnnotationGeneratorException
	{
		unit.recordModifications();
		if (removeAnnotations(typeDeclaration.modifiers(), annotationsSet))
		{
			IDocument doc = AnnotationUtils.getInstance().getDocument(cUnit);
			TextEdit edit = unit.rewrite(doc, null);
			edit.apply(doc);

			saveContent(cUnit, doc);
		}
	}

	private void removeFieldAnnotations(IField field, IType declaringType, ICompilationUnit declaringTypeCompUnit, Set<String> annotationsSet) throws CoreException, MalformedTreeException, BadLocationException, FileNotFoundException, AnnotationGeneratorException
	{
		ICompilationUnit fcUnit = field.getCompilationUnit();
		String className = declaringType.getElementName();
		CompilationUnit fUnit = ASTUtils.getInstance().createCompilationUnit(fcUnit, null);

		BodyDeclaration fBodyDeclaration = ASTUtils.getInstance().getTypeDeclaration(className, fUnit);
		fBodyDeclaration = ASTUtils.getInstance().getFieldDeclaration(field, (TypeDeclaration) fBodyDeclaration);

		fUnit.recordModifications();
		if (removeAnnotations(fBodyDeclaration.modifiers(), annotationsSet))
		{
			IDocument doc = getDocument(declaringTypeCompUnit);
			TextEdit edit = fUnit.rewrite(doc, null);
			edit.apply(doc);

			saveContent(declaringTypeCompUnit, doc);
		}
	}

	private void removeMethodAnnotations(IMethod method, IType declaringType, ICompilationUnit declaringTypeCompUnit, Set<String> annotationsSet) throws CoreException, MalformedTreeException, BadLocationException, FileNotFoundException, AnnotationGeneratorException
	{
		ICompilationUnit mcUnit = method.getCompilationUnit();
		String className = declaringType.getElementName();
		CompilationUnit mUnit = ASTUtils.getInstance().createCompilationUnit(mcUnit, null);

		BodyDeclaration mBodyDeclaration = ASTUtils.getInstance().getTypeDeclaration(className, mUnit);
		mBodyDeclaration = ASTUtils.getInstance().getMethodDeclaration(method, (TypeDeclaration) mBodyDeclaration);
		mUnit.recordModifications();
		if (removeAnnotations(mBodyDeclaration.modifiers(), annotationsSet))
		{
			IDocument doc = getDocument(declaringTypeCompUnit);
			TextEdit edit = mUnit.rewrite(doc, null);
			edit.apply(doc);

			saveContent(declaringTypeCompUnit, doc);
		}
	}

	private void removeParamAnnotations(ITypeParameter param, IType declaringType, ICompilationUnit declaringTypeCompUnit, Set<String> annotationsSet, String paramName) throws CoreException, MalformedTreeException, BadLocationException, FileNotFoundException, AnnotationGeneratorException
	{
		IMethod tmpMethod = (IMethod)param.getDeclaringMember();
		//TODO check this
		//param.getParent();
		String className = declaringType.getElementName();
		ICompilationUnit mcUnit = tmpMethod.getCompilationUnit();
		CompilationUnit mUnit = ASTUtils.getInstance().createCompilationUnit(mcUnit, null);

		BodyDeclaration mBodyDeclaration = ASTUtils.getInstance().getTypeDeclaration(className, mUnit);
		mBodyDeclaration = ASTUtils.getInstance().getMethodDeclaration(tmpMethod, (TypeDeclaration) mBodyDeclaration);
		mUnit.recordModifications();

		for (Object object : ((MethodDeclaration) mBodyDeclaration).parameters())
		{
			if (object instanceof SingleVariableDeclaration)
			{
			  SingleVariableDeclaration svd = (SingleVariableDeclaration) object;
				if ((paramName == null || svd.getName().toString().equals(paramName)) &&
				        removeAnnotations(svd.modifiers(), annotationsSet))
				{
					IDocument doc = getDocument(declaringTypeCompUnit);
					TextEdit edit = mUnit.rewrite(doc, null);
					edit.apply(doc);
					
					saveContent(declaringTypeCompUnit, doc);
				}
			}
		}
	}
	
	private void saveContent(ICompilationUnit cUnit, IDocument doc) throws FileNotFoundException, JavaModelException, AnnotationGeneratorException
	{
		IStatus status = (new EditResourcesManager()).setFileEditable((IFile) cUnit.getResource());
		if(status.getSeverity() == IStatus.OK )
		{
			fileUtils.setCompilationUnitContentAndSaveDirtyEditors(cUnit, doc.get(), true, null);
		}
		else
		{
			throw new AnnotationGeneratorException("Annotattion could not be stored, the file is not writable", //$NON-NLS-1$
											JaxWsUtilMessages.AnnotationCannotBeStoredMsg);
		}
	}
	
	/**
	 * Removes specific Annotation of specified IJavaElement.
	 * 
	 * @param javaElement - IJavaElement which will be used as starting poin for removing the Annotation.
	 * @param annotationName - String which is the representation Name of the Annotation, which will be removed.
	 * 
	 * @throws AnnotationGeneratorException 
	 * @throws AnnotationGeneratorException
	 *             thown if AST TypeDeclaration cannot be found for <code>type</code> and also is used as wrapper in case {@link CoreException} or
	 *             {@link BadLocationException} is thrown while processing.
	 * @throws BadLocationException 
	 * @throws CoreException 
	 * @throws FileNotFoundException 
	 * @throws MalformedTreeException 
	 */
	public void removeAnnotation(IJavaElement javaElement, String annotationName) throws AnnotationGeneratorException, FileNotFoundException, CoreException, BadLocationException
	{
		if(javaElement instanceof IType)
		{
			IType type = (IType)javaElement;
			ICompilationUnit cUnit = type.getCompilationUnit();
			String className = type.getElementName();
			CompilationUnit unit = ASTUtils.getInstance().createCompilationUnit(cUnit, null);

			AbstractTypeDeclaration typeDeclaration = ASTUtils.getInstance().getTypeDeclaration(className, unit);
			if (typeDeclaration == null)
			{
				throw new AnnotationGeneratorException("typeDeclaration should not be null", //$NON-NLS-1$
												MessageFormat.format(JaxWsUtilMessages.AnnotationUtils_ParamShouldNotBeNullMsg, "typeDeclaration")); //$NON-NLS-1$
			}
			
			removeTypeAnnotation(type, typeDeclaration, unit, cUnit, annotationName);

		}
		
		if(javaElement instanceof IField)
		{
			IField field = (IField)javaElement;
			IType declaringType = field.getDeclaringType();
			ICompilationUnit declaringTypeCompUnit = declaringType.getCompilationUnit();
			
			removeFieldAnnotation(field, declaringType, declaringTypeCompUnit, annotationName);
		}
		
		if(javaElement instanceof IMethod)
		{
			IMethod method = (IMethod)javaElement;
			IType declaringType = method.getDeclaringType();
			ICompilationUnit declaringTypeCompUnit = declaringType.getCompilationUnit();
			
			removeMethodAnnotation(method, declaringType, declaringTypeCompUnit, annotationName);
		}
		
		if(javaElement instanceof ITypeParameter)
		{
			ITypeParameter typeParameter = (ITypeParameter)javaElement;
			IMethod tmpMethod = (IMethod) typeParameter.getDeclaringMember();
			//TODO check this
			//param.getParent();
			IType declaringType = tmpMethod.getDeclaringType();
			ICompilationUnit declaringTypeCompUnit = declaringType.getCompilationUnit();

			removeParamAnnotation(typeParameter, declaringType, declaringTypeCompUnit, annotationName);
		}
	}
	
	private void removeTypeAnnotation(IType type, AbstractTypeDeclaration typeDeclaration, CompilationUnit unit, ICompilationUnit cUnit, String annotationName) throws CoreException, MalformedTreeException, BadLocationException, FileNotFoundException, AnnotationGeneratorException
	{
		unit.recordModifications();
		if (removeAnnotation(typeDeclaration.modifiers(), annotationName))
		{
			IDocument doc = AnnotationUtils.getInstance().getDocument(cUnit);
			TextEdit edit = unit.rewrite(doc, null);
			edit.apply(doc);

			saveContent(cUnit, doc);
		}
	}

	private void removeFieldAnnotation(IField field, IType declaringType, ICompilationUnit declaringTypeCompUnit, String annotationName) throws CoreException, MalformedTreeException, BadLocationException, FileNotFoundException, AnnotationGeneratorException
	{
		ICompilationUnit fcUnit = field.getCompilationUnit();
		String className = declaringType.getElementName();
		CompilationUnit fUnit = ASTUtils.getInstance().createCompilationUnit(fcUnit, null);

		BodyDeclaration fBodyDeclaration = ASTUtils.getInstance().getTypeDeclaration(className, fUnit);
		fBodyDeclaration = ASTUtils.getInstance().getFieldDeclaration(field, (TypeDeclaration) fBodyDeclaration);

		fUnit.recordModifications();
		if (removeAnnotation(fBodyDeclaration.modifiers(), annotationName))
		{
			IDocument doc = getDocument(declaringTypeCompUnit);
			TextEdit edit = fUnit.rewrite(doc, null);
			edit.apply(doc);

			saveContent(declaringTypeCompUnit, doc);
		}
	}

	private void removeMethodAnnotation(IMethod method, IType declaringType, ICompilationUnit declaringTypeCompUnit, String annotationName) throws CoreException, MalformedTreeException, BadLocationException, FileNotFoundException, AnnotationGeneratorException
	{
		ICompilationUnit mcUnit = method.getCompilationUnit();
		String className = declaringType.getElementName();
		CompilationUnit mUnit = ASTUtils.getInstance().createCompilationUnit(mcUnit, null);

		BodyDeclaration mBodyDeclaration = ASTUtils.getInstance().getTypeDeclaration(className, mUnit);
		mBodyDeclaration = ASTUtils.getInstance().getMethodDeclaration(method, (TypeDeclaration) mBodyDeclaration);
		mUnit.recordModifications();
		if(removeAnnotation(mBodyDeclaration.modifiers(), annotationName))
		{
			IDocument doc = getDocument(declaringTypeCompUnit);
			TextEdit edit = mUnit.rewrite(doc, null);
			edit.apply(doc);

			saveContent(declaringTypeCompUnit, doc);
		}
	}

	private void removeParamAnnotation(ITypeParameter param, IType declaringType, ICompilationUnit declaringTypeCompUnit, String annotationName) throws CoreException, MalformedTreeException, BadLocationException, FileNotFoundException, AnnotationGeneratorException
	{
		IMethod tmpMethod = (IMethod)param.getDeclaringMember();
		//TODO check this
		//param.getParent();
		String className = declaringType.getElementName();
		ICompilationUnit mcUnit = tmpMethod.getCompilationUnit();
		className = tmpMethod.getParent().getElementName();
		CompilationUnit mUnit = ASTUtils.getInstance().createCompilationUnit(mcUnit, null);

		BodyDeclaration mBodyDeclaration = ASTUtils.getInstance().getTypeDeclaration(className, mUnit);
		mBodyDeclaration = ASTUtils.getInstance().getMethodDeclaration(tmpMethod, (TypeDeclaration) mBodyDeclaration);

		mUnit.recordModifications();
		for (Object object : ((MethodDeclaration) mBodyDeclaration).parameters())
		{
			if (object instanceof SingleVariableDeclaration)
			{
				if (removeAnnotation(((SingleVariableDeclaration) object).modifiers(), annotationName))
				{
					IDocument doc = getDocument(declaringTypeCompUnit);
					TextEdit edit = mUnit.rewrite(doc, null);
					edit.apply(doc);

					saveContent(declaringTypeCompUnit, doc);
				}
			}
		}
	}

	/**
	 * Removes specific annotation from the list of modifiers.
	 * 
	 * @param modifiers
	 * @param annotationName
	 * 
	 * @return boolean value, which represents wheter the annotation is removed or not.
	 */
	@SuppressWarnings("unchecked")
	private boolean removeAnnotation(List modifiers, String annotationName)
	{
		Annotation[] mAnnotations = extractAnnotations(modifiers);
		for (Annotation mAnnotation : mAnnotations)
		{
			if(validateAnnotatation(mAnnotation, annotationName))
			{
				modifiers.remove(mAnnotation);
				return true;
			}
		}
		
		return false;
	}

	@SuppressWarnings("unchecked")
	private boolean removeAnnotations(List modifiers, Set<String> annotationsSet)
	{
		boolean changed = false;
		Annotation[] mAnnotations = extractAnnotations(modifiers);
		for (int mai = 0; mai < mAnnotations.length; mai++)
		{
			if (annotationsSet != null)
			{
				if (annotationsSet.contains(mAnnotations[mai].getTypeName().getFullyQualifiedName()))
				{
					modifiers.remove(mAnnotations[mai]);
					changed = true;
				}
			} else
			{
				modifiers.remove(mAnnotations[mai]);
				changed = true;
			}
		}

		return changed;
	}

	@SuppressWarnings("unchecked")
	private Annotation[] extractAnnotations(List modifiers)
	{
		Iterator iterator = modifiers.iterator();
		Set<Annotation> annotationsSet = new HashSet<Annotation>();

		while (iterator.hasNext())
		{
			IExtendedModifier modif = (IExtendedModifier) iterator.next();
			if (modif.isAnnotation())
			{
				annotationsSet.add((Annotation) modif);
			}
		}

		return annotationsSet.toArray(new Annotation[annotationsSet.size()]);
	}

	private boolean validateAnnotatation(Annotation mAnnotation, String annotationName)
	{
		String mAnnotationString = mAnnotation.toString();
		int index = mAnnotationString.indexOf("("); //$NON-NLS-1$
		if(index == -1)
		{
			mAnnotationString = mAnnotationString.trim();
		}
		else
		{
			mAnnotationString = mAnnotationString.substring(0, index).trim();
		}
		
		if(mAnnotationString.endsWith(annotationName))
		{
			return true;
		}
		 
		return false;
	}
}
