/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 */
package org.apache.qpid.server.model;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
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.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;

import org.apache.qpid.server.License;

@SupportedAnnotationTypes(ConfiguredObjectRegistrationGenerator.MANAGED_OBJECT_CANONICAL_NAME)
public class ConfiguredObjectRegistrationGenerator extends AbstractProcessor
{

    public static final String MANAGED_OBJECT_CANONICAL_NAME = "org.apache.qpid.server.model.ManagedObject";

    private Map<String, Set<String>> _managedObjectClasses = new HashMap<>();

    private Map<String, String> _typeMap = new HashMap<>();
    private Map<String, String> _categoryMap = new HashMap<>();
    private boolean _elementProcessingDone;

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

    @Override
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv)
    {
        if (!_elementProcessingDone)
        {
            final Elements elementUtils = processingEnv.getElementUtils();
            final TypeElement managedObjectElement = elementUtils.getTypeElement(MANAGED_OBJECT_CANONICAL_NAME);
            try
            {
                roundEnv.getElementsAnnotatedWith(managedObjectElement).stream()
                        .map(element -> elementUtils.getPackageOf(element))
                        .flatMap(packageElement -> packageElement.getEnclosedElements().stream())
                        .filter(element -> hasAnnotation(element, managedObjectElement))
                        .forEach(annotatedElement -> processAnnotatedElement(elementUtils,
                                                                             managedObjectElement,
                                                                             annotatedElement));

                for (Map.Entry<String, Set<String>> entry : _managedObjectClasses.entrySet())
                {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE,
                                                             String.format("Generating CO registration for package '%s'", entry.getKey()));
                    generateRegistrationFile(entry.getKey(), entry.getValue());
                }
                _managedObjectClasses.clear();
                _typeMap.clear();
                _categoryMap.clear();

                _elementProcessingDone = true;

            }
            catch (Exception e)
            {
                processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Error: " + e.getLocalizedMessage());
            }
        }
        return false;
    }

    private void processAnnotatedElement(final Elements elementUtils,
                                         final TypeElement annotationElement,
                                         final Element e)
    {
        if (e.getKind().equals(ElementKind.INTERFACE) || e.getKind().equals(ElementKind.CLASS))
        {
            PackageElement packageElement = elementUtils.getPackageOf(e);
            String packageName = packageElement.getQualifiedName().toString();
            String className = e.getSimpleName().toString();
            AnnotationMirror annotation = getAnnotation(e, annotationElement);

            AnnotationValue registerValue = getAnnotationValue(annotation, "register");

            if(registerValue == null || (Boolean) registerValue.getValue() )
            {
                AnnotationValue typeValue = getAnnotationValue(annotation, "type");

                if (typeValue != null)
                {
                    _typeMap.put(packageName + "." + className, (String) typeValue.getValue());
                    processingEnv.getMessager()
                            .printMessage(Diagnostic.Kind.NOTE,
                                          "looking for " + packageName + "." + className);
                    _categoryMap.put(packageName + "." + className, getCategory((TypeElement) e));

                }


                Set<String> classNames = _managedObjectClasses.get(packageName);
                if (classNames == null)
                {
                    classNames = new HashSet<>();
                    _managedObjectClasses.put(packageName, classNames);
                }
                classNames.add(className);
            }
        }
    }

    private AnnotationValue getAnnotationValue(final AnnotationMirror annotation, final String attribute)
    {
        for(Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : annotation.getElementValues().entrySet())
        {
            if(entry.getKey().getSimpleName().toString().equals(attribute))
            {
                return entry.getValue();
            }
        }
        return null;
    }

    private boolean hasAnnotation(final Element element, final TypeElement annotationElement)
    {
        return getAnnotation(element, annotationElement) != null;
    }

    private AnnotationMirror getAnnotation(final Element e, final TypeElement annotationElement)
    {
        for(AnnotationMirror a : e.getAnnotationMirrors())
        {
            if (a.getAnnotationType().asElement().equals(annotationElement))
            {
                return a;
            }
        }
        return null;
    }

    private String getCategory(final TypeElement e)
    {
        Elements elementUtils = processingEnv.getElementUtils();
        TypeElement annotationElement = elementUtils.getTypeElement(MANAGED_OBJECT_CANONICAL_NAME);
        String category = null;
        List<? extends AnnotationMirror> annotationMirrors = e.getAnnotationMirrors();
        if(annotationMirrors != null)
        {
            for (AnnotationMirror a : annotationMirrors)
            {
                if (a.getAnnotationType().asElement().equals(annotationElement))
                {
                    category = e.getSimpleName().toString().toLowerCase();

                    for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : a.getElementValues()
                            .entrySet())
                    {
                        if (entry.getKey().getSimpleName().toString().equals("category"))
                        {
                            if (!Boolean.TRUE.equals(entry.getValue().getValue()))
                            {
                                category = null;
                            }

                            break;
                        }
                    }
                    break;
                }
            }
        }

        if (category == null)
        {
            for (TypeMirror interfaceMirror : e.getInterfaces())
            {
                category = getCategory((TypeElement) processingEnv.getTypeUtils().asElement(interfaceMirror));
                if (category != null)
                {
                    break;
                }
            }
        }

        if (category == null && e.getSuperclass() != null)
        {
            TypeElement parent = (TypeElement) processingEnv.getTypeUtils().asElement(e.getSuperclass());
            if(parent != null)
            {
                category = getCategory(parent);
            }
        }

        return category;

    }

    private void generateRegistrationFile(final String packageName, final Set<String> classNames)
    {
        final String className = "ConfiguredObjectRegistrationImpl";
        final String qualifiedClassName = packageName + "." + className;

        try
        {


            JavaFileObject factoryFile = processingEnv.getFiler().createSourceFile(qualifiedClassName);

            PrintWriter pw = new PrintWriter(new OutputStreamWriter(factoryFile.openOutputStream(), "UTF-8"));
            pw.println("/*");
            for (String headerLine : License.LICENSE)
            {
                pw.println(" *" + headerLine);
            }
            pw.println(" */");
            pw.println();
            pw.print("package ");
            pw.print(packageName);
            pw.println(";");
            pw.println();

            pw.println("import java.util.Collections;");
            pw.println("import java.util.HashSet;");
            pw.println("import java.util.Set;");
            pw.println();
            pw.println("import org.apache.qpid.server.model.ConfiguredObject;");
            pw.println("import org.apache.qpid.server.plugin.ConfiguredObjectRegistration;");
            pw.println("import org.apache.qpid.server.plugin.PluggableService;");
            pw.println();
            pw.println("@PluggableService");
            pw.println("public class " + className + " implements ConfiguredObjectRegistration");
            pw.println("{");
            pw.println("    private final Set<Class<? extends ConfiguredObject>> _implementations;");
            pw.println();
            pw.println("    public " + className + "()");
            pw.println("    {");
            pw.println("        Set<Class<? extends ConfiguredObject>> implementations = new HashSet<>();");
            for(String implementationName : classNames)
            {
                String qualifiedImplementationName = packageName + "." + implementationName;
                if(_typeMap.get(qualifiedImplementationName) != null && _categoryMap.get(qualifiedImplementationName) != null)
                {
                    pw.println("        if(!Boolean.getBoolean(\"qpid.type.disabled:"
                               +_categoryMap.get(qualifiedImplementationName)
                               +"."+_typeMap.get(qualifiedImplementationName)+"\"))");
                    pw.println("        {");
                    pw.println("             implementations.add("+implementationName+".class);");
                    pw.println("        }");

                }
                else
                {
                    pw.println("        implementations.add(" + implementationName + ".class);");
                }
            }
            pw.println("        _implementations = Collections.unmodifiableSet(implementations);");
            pw.println("    }");
            pw.println();
            pw.println("    public String getType()");
            pw.println("    {");
            pw.println("        return \""+packageName+"\";");
            pw.println("    }");
            pw.println();
            pw.println("    public Set<Class<? extends ConfiguredObject>> getConfiguredObjectClasses()");
            pw.println("    {");
            pw.println("        return _implementations;");
            pw.println("    }");
            pw.println();


            pw.println("}");

            pw.close();
        }
        catch (IOException e)
        {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                                                     "Failed to write file: "
                                                     + qualifiedClassName
                                                     + " - "
                                                     + e.getLocalizedMessage()
                                                    );
        }
    }

}
