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

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

import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
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.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.AbstractAnnotationValueVisitor6;
import javax.lang.model.util.ElementScanner6;

import org.eclipse.jdt.compiler.apt.tests.processors.base.BaseProcessor;

/**
 * Processor that tests a variety of Visitors
 */
@SupportedAnnotationTypes({"*"})
@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class VisitorProc extends BaseProcessor
{
	/**
	 * This visitor is invoked on the top-level types in resources/targets/model.
	 * We expect to see each of the visitX() methods get hit as a result.
	 */
	private static class ElementVisitorTester extends ElementScanner6<Void, Void> {
		
		public enum Visited { TYPE, EXECUTABLE, VARIABLE, TYPEPARAM, PACKAGE, UNKNOWN }
		
		private EnumSet<Visited> _visited = EnumSet.noneOf(Visited.class);
		
		public boolean checkVisits() {
			boolean asExpected = true;
			asExpected &= _visited.contains(Visited.TYPE);
			asExpected &= _visited.contains(Visited.EXECUTABLE);
			asExpected &= _visited.contains(Visited.VARIABLE);
			// TODO: Following two cases not yet implemented:
			//asExpected &= _visited.contains(Visited.TYPEPARAM);
			//asExpected &= _visited.contains(Visited.PACKAGE);
			return asExpected;
		}
		
        /**
         * Check that we can visit types.
         * @return true if all tests passed
         */
        @Override
        public Void visitType(TypeElement e, Void p) {
        	_visited.add(Visited.TYPE);
        	// Scan the type's subtypes, fields, and methods
            return super.visitType(e, p);
        }
        
        /**
         * Check that we can visit methods.
         */
        @Override
        public Void visitExecutable(ExecutableElement e, Void p) {
        	_visited.add(Visited.EXECUTABLE);
        	// Scan the method's parameters
            return super.visitExecutable(e, p);
        }
        
        /**
         * Check that we can visit variables.
         */
        @Override
        public Void visitVariable(VariableElement e, Void p) {
        	_visited.add(Visited.VARIABLE);
            // Variables do not enclose any elements, so no need to call super.
        	return null;
        }

        /**
         * Check that we can visit type parameters.
         */
        @Override
        public Void visitTypeParameter(TypeParameterElement e, Void p) {
        	_visited.add(Visited.TYPEPARAM);
            // Type parameters do not enclose any elements, so no need to call super.
        	return null;
        }
        
        /**
         * Check that we can visit packages.
         */
        @Override
        public Void visitPackage(PackageElement e, Void p) {
        	_visited.add(Visited.PACKAGE);
            // We don't want to scan the package's types here, so don't call super.
        	return null;
        }
        
        /**
         * This should not actually be encountered.
         */
        @Override
        public Void visitUnknown(Element e, Void p) {
        	_visited.add(Visited.UNKNOWN);
        	return null;
        }
        
	}
	
	/*
	 * The specific values checked by this visitor correspond to values in targets.model.pc.TypedAnnos.java
	 */
	private static class AnnotationVisitorTester extends AbstractAnnotationValueVisitor6<Void, Void> {

		public enum Visited { ANNOTATION, ARRAY, BOOLEAN, BYTE, CHAR, DOUBLE, ENUMCONSTANT, FLOAT, INT, LONG, SHORT, STRING, TYPE }
		
		private EnumSet<Visited> _visited = EnumSet.noneOf(Visited.class);
		
		public boolean checkVisits() {
			boolean asExpected = true;
			asExpected &= _visited.contains(Visited.ANNOTATION);
			asExpected &= _visited.contains(Visited.ARRAY);
			asExpected &= _visited.contains(Visited.BOOLEAN);
			asExpected &= _visited.contains(Visited.BYTE);
			asExpected &= _visited.contains(Visited.CHAR);
			asExpected &= _visited.contains(Visited.DOUBLE);
			asExpected &= _visited.contains(Visited.ENUMCONSTANT);
			asExpected &= _visited.contains(Visited.FLOAT);
			asExpected &= _visited.contains(Visited.INT);
			asExpected &= _visited.contains(Visited.LONG);
			asExpected &= _visited.contains(Visited.SHORT);
			asExpected &= _visited.contains(Visited.STRING);
			asExpected &= _visited.contains(Visited.TYPE);
			return asExpected;
		}
		
		@Override
		public Void visitAnnotation(AnnotationMirror a, Void p)
		{
			if (a != null && a.getElementValues() != null) {
				_visited.add(Visited.ANNOTATION);
			}
			// we could scan the values of the nested annotation here, but that doesn't help our test case
			return null;
		}

		@Override
		public Void visitArray(List<? extends AnnotationValue> vals, Void p)
		{
			if ( null != vals && vals.size() == 2 ) {
				if ( vals.iterator().next().getValue() instanceof TypeMirror) {
					_visited.add(Visited.ARRAY);
				}
			}
			// we could scan the array values here, but that doesn't help our test case
			return null;
		}

		@Override
		public Void visitBoolean(boolean b, Void p)
		{
			if (b) {
				_visited.add(Visited.BOOLEAN);
			}
			return null;
		}

		@Override
		public Void visitByte(byte b, Void p)
		{
			if (b == 3) {
				_visited.add(Visited.BYTE);
			}
			return null;
		}

		@Override
		public Void visitChar(char c, Void p)
		{
			if (c == 'c') { 
				_visited.add(Visited.CHAR);
			}
			return null;
		}

		@Override
		public Void visitDouble(double d, Void p)
		{
			if (d == 6.3) {
				_visited.add(Visited.DOUBLE);
			}
			return null;
		}

		@Override
		public Void visitEnumConstant(VariableElement c, Void p)
		{
			if (c.getKind() == ElementKind.ENUM_CONSTANT) {
				if ("A".equals(c.getSimpleName().toString())) {
					_visited.add(Visited.ENUMCONSTANT);
				}
			}
			return null;
		}

		@Override
		public Void visitFloat(float f, Void p)
		{
			if (f == 26.7F) {
				_visited.add(Visited.FLOAT);
			}
			return null;
		}

		@Override
		public Void visitInt(int i, Void p)
		{
			if (i == 19) {
				_visited.add(Visited.INT);
			}
			return null;
		}

		@Override
		public Void visitLong(long i, Void p)
		{
			if (i == 300L) {
				_visited.add(Visited.LONG);
			}
			return null;
		}

		@Override
		public Void visitShort(short s, Void p)
		{
			if (s == 289) {
				_visited.add(Visited.SHORT);
			}
			return null;
		}

		@Override
		public Void visitString(String s, Void p)
		{
			if ("foo".equals(s)) {
				_visited.add(Visited.STRING);
			}
			return null;
		}

		@Override
		public Void visitType(TypeMirror t, Void p)
		{
			if ("java.lang.Exception".equals(t.toString())) {
				_visited.add(Visited.TYPE);
			}
			return null;
		}
		
	}
	
	@Override
	public synchronized void init(ProcessingEnvironment processingEnv)
	{
		super.init(processingEnv);
	}

	@Override
	public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)
	{
		if (roundEnv.processingOver()) {
			return false;
		}
		Map<String, String> options = processingEnv.getOptions();
		if (!options.containsKey(this.getClass().getName())) {
			// Disable this processor unless we are intentionally performing the test.
			return false;
		}
		ElementVisitorTester elementVisitor = new ElementVisitorTester();
		elementVisitor.scan(roundEnv.getRootElements(), null);
		if (!elementVisitor.checkVisits()) {
			reportError("Element visitor was not visited as expected");
			return false;
		}
		
		AnnotationVisitorTester annoValVisitor = new AnnotationVisitorTester();
		TypeElement typedAnnosDecl = _elementUtils.getTypeElement("org.eclipse.jdt.compiler.apt.tests.annotations.TypedAnnos");
		if (null == typedAnnosDecl) {
			reportError("Couldn't find targets.model.pc.AnnotatedWithManyTypes");
			return false;
		}
		for (TypeElement anno : annotations) {
			if (typedAnnosDecl.equals(anno.getEnclosingElement())) {
				for (Element elem : roundEnv.getElementsAnnotatedWith(anno)) {
					for (AnnotationMirror annoMirror : elem.getAnnotationMirrors()) {
						if (anno.equals(annoMirror.getAnnotationType().asElement())) {
							Map<? extends ExecutableElement, ? extends AnnotationValue> values = annoMirror.getElementValues();
							for (AnnotationValue val : values.values()) {
								val.accept(annoValVisitor, null);
							}
						}
					}
				}
			}
		}
		if (!annoValVisitor.checkVisits()) {
			reportError("Annotation value visitor was not visited as expected");
			return false;
		}

		reportSuccess();
		return false;
	}

}
