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

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.NoSuchFileException;
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.Filer;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.NoType;
import javax.lang.model.type.TypeMirror;
import javax.tools.Diagnostic;
import javax.tools.FileObject;
import javax.tools.StandardLocation;

import org.apache.qpid.server.License;

public class PluggableProcessor extends AbstractProcessor
{
    private Map<String, Set<String>> factoryImplementations = new HashMap<>();


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

    @Override
    public Set<String> getSupportedAnnotationTypes()
    {
        return Collections.singleton(PluggableService.class.getName());
    }

    @Override
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv)
    {
        if(roundEnv.processingOver())
        {
            generateServiceFiles(processingEnv.getFiler());

            return true;
        }
        try
        {

            for (Element e : roundEnv.getElementsAnnotatedWith(PluggableService.class))
            {

                if (e.getKind() == ElementKind.CLASS)
                {
                    TypeElement classElement = (TypeElement) e;
                    Set<String> pluggableTypes = getPluggableTypes(classElement);
                    for(String pluggableType : pluggableTypes)
                    {
                        Set<String> existingFactories = factoryImplementations.get(pluggableType);
                        if(existingFactories == null)
                        {
                            existingFactories = new HashSet<>();
                            factoryImplementations.put(pluggableType, existingFactories);
                        }
                        existingFactories.add(classElement.getQualifiedName().toString());
                    }
                }
            }

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

        return true;
    }

    private Set<String> getPluggableTypes(final TypeElement classElement)
    {

        final Set<String> types = new HashSet<>();

        List<? extends TypeMirror> interfaces = classElement.getInterfaces();
        for(TypeMirror typeMirror : interfaces)
        {
            TypeElement interfaceElt = (TypeElement) processingEnv.getTypeUtils().asElement(typeMirror);
            if(interfaceElt.getQualifiedName().toString().equals("org.apache.qpid.server.plugin.Pluggable"))
            {
                types.add(classElement.getQualifiedName().toString());
            }
            else
            {
                types.addAll(getPluggableTypes(interfaceElt));
            }

        }
        TypeMirror superClass = classElement.getSuperclass();
        if(!(superClass instanceof NoType))
        {
            types.addAll(getPluggableTypes((TypeElement) processingEnv.getTypeUtils().asElement(superClass)));
        }

        return types;
    }

    private void generateServiceFiles(Filer filer)
    {
        for(String serviceName : factoryImplementations.keySet())
        {
            processingEnv.getMessager()
                    .printMessage(Diagnostic.Kind.NOTE, "Generating service file for " + serviceName);

            String relativeName = "META-INF/services/" + serviceName;
            loadExistingServicesFile(filer, serviceName);
            try
            {
                FileObject serviceFile = filer.createResource(StandardLocation.CLASS_OUTPUT, "", relativeName);
                try(PrintWriter pw = new PrintWriter(new OutputStreamWriter(serviceFile.openOutputStream(), "UTF-8")))
                {
                    for (String headerLine : License.LICENSE)
                    {
                        pw.println("#" + headerLine);
                    }
                    pw.println("#");
                    pw.println("# Note: Parts of this file are auto-generated from annotations.");
                    pw.println("#");
                    for (String implementation : factoryImplementations.get(serviceName))
                    {
                        pw.println(implementation);
                    }
                }
            }
            catch (IOException e)
            {
                processingEnv.getMessager()
                        .printMessage(Diagnostic.Kind.ERROR,
                                      "Failed to write services file: "
                                      + relativeName
                                      + " - "
                                      + e.getLocalizedMessage()
                                     );
            }
        }
    }

    private String loadExistingServicesFile(final Filer filer, String serviceName)
    {
        String relativeName = "META-INF/services/" + serviceName;
        try
        {
            FileObject existingFile = filer.getResource(StandardLocation.CLASS_OUTPUT, "", relativeName);
            try(BufferedReader r = new BufferedReader(new InputStreamReader(existingFile.openInputStream(), "UTF-8")))
            {
                String line;
                while ((line = r.readLine()) != null)
                {
                    if (!line.matches(" *#"))
                    {
                        factoryImplementations.get(serviceName).add(line);
                    }
                }
            }
        }
        catch (NoSuchFileException | FileNotFoundException e)
        {
            // no existing file (ignore)
        }
        catch (IOException e)
        {
            String errorMessage;
            try(StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw))
            {
                e.printStackTrace(pw);
                errorMessage = sw.toString();
            }
            catch (IOException ioe)
            {
                errorMessage = e.getLocalizedMessage();
            }
            processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
                                                     "Error loading existing services file: " + relativeName
                                                     + " - " + errorMessage);
        }
        return relativeName;
    }

}
