/*
 * Copyright 2015, Yahoo Inc.
 * Copyrights licensed under the Apache 2.0 License.
 * See the accompanying LICENSE file for terms.
 */
package com.yahoo.squidb.processor;

import com.yahoo.squidb.annotations.ModelGenErrors;

import java.util.HashSet;
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.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;

public class ErrorLoggingProcessor extends AbstractProcessor {

    private Set<String> supportedAnnotationTypes = new HashSet<>();
    private Messager messager;

    public ErrorLoggingProcessor() {
        supportedAnnotationTypes.add(ModelGenErrors.class.getName());
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latestSupported();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        return supportedAnnotationTypes;
    }

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        this.messager = processingEnv.getMessager();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
        for (TypeElement annotationType : annotations) {
            if (supportedAnnotationTypes.contains(annotationType.getQualifiedName().toString())) {
                for (Element element : env.getElementsAnnotatedWith(annotationType)) {
                    ModelGenErrors errorsToLog = element.getAnnotation(ModelGenErrors.class);
                    logErrors(errorsToLog);
                }
            }
        }
        return true;
    }

    private void logErrors(ModelGenErrors errors) {
        // TODO: Implement error logging
    }
}

@@ -168,16 +168,58 @@
 essor;%0A%0A
+import com.yahoo.aptutils.utils.AptUtils;%0A
 import c
@@ -289,16 +289,39 @@
 ashSet;%0A
+import java.util.List;%0A
 import j
@@ -393,53 +393,8 @@
 or;%0A
-import javax.annotation.processing.Messager;%0A
 impo
@@ -539,16 +539,115 @@
 ersion;%0A
+import javax.lang.model.element.AnnotationMirror;%0Aimport javax.lang.model.element.AnnotationValue;%0A
 import j
@@ -723,16 +723,88 @@
 Element;
+%0Aimport javax.lang.model.type.TypeMirror;%0Aimport javax.tools.Diagnostic;
 %0A%0Apublic
@@ -945,25 +945,22 @@
 ate 
-Messager messager
+AptUtils utils
 ;%0A%0A 
@@ -1452,45 +1452,42 @@
 his.
-messager = processingEnv.getMessager(
+utils = new AptUtils(processingEnv
 );%0A 
@@ -1864,59 +1864,256 @@
     
-ModelGenErrors errorsToLog = element.getAnnotation(
+logErrors(element);%0A                %7D%0A            %7D%0A        %7D%0A        return true;%0A    %7D%0A%0A    @SuppressWarnings(%22unchecked%22)%0A    private void logErrors(Element element) %7B%0A        AnnotationValue errorsArrayValue = utils.getAnnotationValue(element, 
 Mode
@@ -2128,16 +2128,25 @@
 rs.class
+, %22value%22
 );%0A     
@@ -2152,206 +2152,1650 @@
     
-            logErrors(errorsToLog);%0A                %7D%0A            %7D%0A        %7D%0A        return true;%0A    %7D%0A%0A    private void logErrors(ModelGenErrors errors) %7B%0A        // TODO: Imp
+List%3C? extends AnnotationValue%3E errorsList = (List%3C? extends AnnotationValue%3E) errorsArrayValue.getValue();%0A        for (AnnotationValue error : errorsList) %7B%0A            logSingleError(error);%0A        %7D%0A    %7D%0A%0A    private void logSingleError(AnnotationValue singleErrorAnnotation) %7B%0A        AnnotationMirror singleErrorMirror = (AnnotationMirror) singleErrorAnnotation.getValue();%0A%0A        TypeMirror errorClass = utils.getTypeMirrorsFromAnnotationValue(%0A                utils.getAnnotationValueFromMirror(singleErrorMirror, %22specClass%22)).get(0);%0A        String errorMessage = utils.getValuesFromAnnotationValue(%0A                utils.getAnnotationValueFromMirror(singleErrorMirror, %22message%22), String.class).get(0);%0A        List%3CString%3E errorElementValues = utils.getValuesFromAnnotationValue(%0A                utils.getAnnotationValueFromMirror(singleErrorMirror, %22element%22), String.class);%0A        String errorElementName = AptUtils.isEmpty(errorElementValues) ? null : errorElementValues.get(0);%0A%0A        Element errorElement = findErrorElement(errorClass, errorElementName);%0A        utils.getMessager().printMessage(Diagnostic.Kind.ERROR, errorMessage,%0A                errorElement);%0A    %7D%0A%0A    private Element findErrorElement(TypeMirror errorClass, String elementName) %7B%0A        Element errorClassElement = utils.getTypes().asElement(errorClass);%0A        List%3C? extends Element%3E enclosedE
 lement
+s =
  error
- logging
+ClassElement.getEnclosedElements();%0A        for (Element e : enclosedElements) %7B%0A            if (e.getSimpleName().toString().equals(elementName)) %7B%0A                return e;%0A            %7D%0A        %7D%0A        return errorClassElement;
 %0A   

Implement the error logging in ErrorLoggingProcessor