/*******************************************************************************
 * Copyright (c) 2007 BEA Systems, Inc. 
 * 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:
 *    wharley@bea.com - initial API and implementation
 *    
 *******************************************************************************/

package org.eclipse.jdt.compiler.apt.tests.processors.messager;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedOptions;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic.Kind;

/**
 * A processor that uses the Messager interface to report errors against various
 * elements in the targets.model resource hierarchy.  To enable this processor, add 
 * -Aorg.eclipse.jdt.compiler.apt.tests.processors.messager.MessagerProc to the command line.
 * <p>
 * The idea of this processor is that it calls the Messager interface with various messages
 * on various elements.  If the interface itself fails, an error is reported via the
 * reportError() method, which sets a system property that the calling test case will
 * inspect.  Then, following processor execution, the calling test case will inspect all
 * the messages that were passed to Messager, to make sure that they all made it into the
 * compiler error output in the expected way.
 * 
 * @since 3.3
 */
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedOptions("org.eclipse.jdt.compiler.apt.tests.processors.messager.MessagerProc")
public class MessagerProc extends AbstractProcessor {
	
	private static final String CLASSNAME = MessagerProc.class.getName();
	
	/**
	 * Report an error to the test case code.  
	 * This is not the same as reporting via Messager!  Use this if some API fails.
	 * @param value will be displayed in the test output, in the event of failure.
	 * Can be anything except "succeeded".
	 */
	public static void reportError(String value) {
		// Uncomment for processor debugging - don't report error
		// value = "succeeded";
		System.setProperty(CLASSNAME, value);
	}
	
	/**
	 * Report success to the test case code
	 */
	public static void reportSuccess() {
		System.setProperty(CLASSNAME, "succeeded");
	}

	private Elements _elementUtils;
	//private Types _typeUtils;
	private Messager _messager;

	// Initialized in collectElements()
	private TypeElement _elementD;
	
	// Initialized in collectElements()
//	private ExecutableElement _methodElement;
	
	// Initialized in collectElements()
	private TypeElement _element2;

	// Initialized in collectElements()
	private AnnotationMirror _annotationMirror;

	// Initialized in collectElements()
	private AnnotationValue _annotationValue;

	// Initialized in collectElements()
	private TypeElement _elementE;

	// Initialized in collectElements()
	private ExecutableElement _methodElement;

	// Initialized in collectElements()
	private VariableElement _variableElement;
	
	// Initialized in collectElements()
	private TypeElement _elementF;

	/* (non-Javadoc)
	 * @see javax.annotation.processing.AbstractProcessor#init(javax.annotation.processing.ProcessingEnvironment)
	 */
	@Override
	public synchronized void init(ProcessingEnvironment processingEnv) {
		super.init(processingEnv);
		_elementUtils = processingEnv.getElementUtils();
		//_typeUtils = processingEnv.getTypeUtils();
		_messager = processingEnv.getMessager();
	}

	// Always return false from this processor, because it supports "*".
	// The return value does not signify success or failure!
	@Override
	public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
		if (roundEnv.processingOver()) {
			// We're not interested in the postprocessing round.
			return false;
		}
		Map<String, String> options = processingEnv.getOptions();
		if (!options.containsKey(CLASSNAME)) {
			// Disable this processor unless we are intentionally performing the test.
			return false;
		}
		
		if (null == _messager) {
			reportError("Env.getMessager() returned null");
			return false;
		}
		
		if (!collectElements()) {
			return false;
		}
		
		if (!printErrorsOnElements()) {
			return false;
		}
		
		MessagerProc.reportSuccess();
		return false;
	}
	
	/**
	 * Collect some elements that will be reused in various tests
	 * @return true if all tests passed
	 */
	private boolean collectElements() {
		_elementD = _elementUtils.getTypeElement("targets.errors.pb.D");
		if (null == _elementD || _elementD.getKind() != ElementKind.CLASS) {
			reportError("Element D was not found or was not a class");
			return false;
		}
//		printVariableElements(_elementD);
		
		_elementE = _elementUtils.getTypeElement("targets.errors.pb.E");
		if (null == _elementE || _elementE.getKind() != ElementKind.CLASS) {
			reportError("Element E was not found or was not a class");
			return false;
		}
//		printVariableElements(_elementE);
		
		_elementF = _elementUtils.getTypeElement("targets.errors.pb.F");
		if (null == _elementF || _elementF.getKind() != ElementKind.CLASS) {
			reportError("Element F was not found or was not a class");
			return false;
		}
//		printVariableElements(_elementF);
		
		List<? extends Element> enclosedElements = _elementE.getEnclosedElements();
		for (Element element : enclosedElements) {
			switch(element.getKind()) {
				case METHOD :
					ExecutableElement executableElement = (ExecutableElement) element;
					StringBuilder builder = new StringBuilder(executableElement.getSimpleName());
					String name = String.valueOf(builder);
					if ("foo".equals(name) && _methodElement == null) {
						_methodElement = executableElement;
					}
					break;
				case FIELD :
					VariableElement variableElement = (VariableElement) element;
					builder = new StringBuilder(variableElement.getSimpleName());
					name = String.valueOf(builder);
					if ("j".equals(name) && _variableElement == null) {
						_variableElement = variableElement;
					}
			}
		}

		if (_methodElement == null) {
			reportError("Element for method foo could not be found");
			return false;
		}
		
		if (_variableElement == null) {
			reportError("Element for field j could not be found");
			return false;
		}

		List<? extends AnnotationMirror> annotationMirrors = _elementD.getAnnotationMirrors();
		for (AnnotationMirror mirror : annotationMirrors) {
			if (_annotationMirror == null) {
				_annotationMirror = mirror;
				break;
			}
		}
		if (_annotationMirror == null) {
			reportError("Annotation mirror was not found");
			return false;
		}
		Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = _annotationMirror.getElementValues();
		Collection<? extends AnnotationValue> values = elementValues.values();
		for (AnnotationValue value : values) {
			if (_annotationValue == null) {
				_annotationValue = value;
				break;
			}
		}
		if (_annotationValue == null) {
			reportError("Annotation value was not found");
			return false;
		}
		
		_element2 = _elementUtils.getTypeElement("java.lang.String");
		if (_element2 == null) {
			reportError("Element for java.lang.String could not be found");
			return false;
		}
//		printVariableElements(_element2);

		return true;
	}
	
	static void printVariableElements(final TypeElement typeElement) {
		List<? extends Element> enclosedElements = typeElement.getEnclosedElements();
		for (Element element : enclosedElements) {
			switch(element.getKind()) {
				case ENUM :
					System.out.println("enum type : " + element.getSimpleName());
					break;
				case CLASS :
					System.out.println("class : " + element.getSimpleName());
					break;
				case INSTANCE_INIT :
					System.out.println("initializer : " + element.getSimpleName());
					break;
				case STATIC_INIT :
					System.out.println("static initializer : " + element.getSimpleName());
					break;
				case FIELD :
					System.out.println("field : " + element.getSimpleName());
					break;
				case CONSTRUCTOR :
					System.out.println("constructor : " + element.getSimpleName());
					ExecutableElement executableElement = (ExecutableElement) element;
					List<? extends VariableElement> parameters = executableElement.getParameters();
					for (VariableElement variableElement : parameters) {
						System.out.print("name = " + variableElement.getSimpleName());
						TypeMirror typeMirror = variableElement.asType();
						System.out.print(" type = " + typeMirror);
						System.out.println(" type kind = " + typeMirror.getKind());
					}
					break;
				case METHOD :
					System.out.println("method : " + element.getSimpleName());
					executableElement = (ExecutableElement) element;
					parameters = executableElement.getParameters();
					for (VariableElement variableElement : parameters) {
						System.out.print("name = " + variableElement.getSimpleName());
						TypeMirror typeMirror = variableElement.asType();
						System.out.print(" type = " + typeMirror);
						System.out.println(" type kind = " + typeMirror.getKind());
					}
			}
		}
	}

	private boolean printErrorsOnElements() {
		_messager.printMessage(Kind.NOTE, "Informational message not associated with an element");
		_messager.printMessage(Kind.ERROR, "Error on element D", _elementD);
		_messager.printMessage(Kind.ERROR, "Error on element D", _elementD, _annotationMirror);
		_messager.printMessage(Kind.ERROR, "Error on element D", _elementD, _annotationMirror, _annotationValue);
		_messager.printMessage(Kind.ERROR, "Error on element java.lang.String", _element2);
		_messager.printMessage(Kind.WARNING, "Warning on method foo", _methodElement);
		_messager.printMessage(Kind.NOTE, "Note for field j", _variableElement);
		return true;
	}
}
