
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.AnnotatedConstruct;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.TypeParameterElement;

@SupportedSourceVersion(SourceVersion.RELEASE_8)
@SupportedAnnotationTypes({"*"})
public class TestProcessor extends AbstractProcessor {

	@Override
	public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
		Set<? extends Element> set = roundEnv.getRootElements();
        for(Iterator<? extends Element> iterator = set.iterator(); iterator.hasNext();) {
            Element element = iterator.next();
            TypeElement typeelement = (TypeElement)element;
            List<? extends TypeParameterElement> typeParams = typeelement.getTypeParameters();
            for (TypeParameterElement typeParameter : typeParams) {
				System.out.println("Processing type parameter: " + typeParameter);
				verifyAnnotations("Incorrect annots on type parameter", typeParameter, new String[]{"@Container(value=[@Marker, @Marker])"});
				verifyAnnotations("Incorrect annots on type parameter mirror", typeParameter.asType(), new String[]{"@Container(value=[@Marker, @Marker])"});
			}
        }
		return false;
	}

	public void reportError(String msg) {
		System.out.println("FAILURE::" + msg);
	}

	private void verifyAnnotations(String msg, AnnotatedConstruct construct, String[] annots) {
		List<? extends AnnotationMirror> annotations = construct.getAnnotationMirrors();
		assertEquals(msg, annots.length, annotations.size());
	}

	public void assertEquals(String msg, int expected, int actual) {
		if (expected != actual) {
			StringBuffer buf = new StringBuffer();
			buf.append(msg);
			buf.append(", expected " + expected + " but was " + actual);
			reportError(buf.toString());
		}
	}
}
