/*
 * 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 createObject 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.tamaya.doc;

import org.apache.tamaya.doc.annot.*;
import org.apache.tamaya.spi.ServiceContextManager;
import org.reflections.Reflections;
import org.reflections.scanners.FieldAnnotationsScanner;
import org.reflections.scanners.MethodAnnotationsScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * Class to read and store the current configuration documentation.
 */
public class ConfigDocumenter {

    private DocumentedConfiguration docs = new DocumentedConfiguration();


    public static ConfigDocumenter getInstance(){
        return ServiceContextManager.getServiceContext()
                .getService(ConfigDocumenter.class, ConfigDocumenter::new);
    }

    public static ConfigDocumenter getInstance(ClassLoader classLoader){
        return ServiceContextManager.getServiceContext(classLoader)
                .getService(ConfigDocumenter.class, ConfigDocumenter::new);
    }

    /**
     * Read documentation from the given classes.
     * @param clazzes the classes to read, not null.
     */
    public void readClasses(Class... clazzes){
        FilterBuilder filterBuilder = new FilterBuilder();
        List<URL> urls = new ArrayList<>(clazzes.length);
        for(Class clazz:clazzes){
//            filterBuilder.exclude(".*");
            filterBuilder.include(clazz.getName()+".*");
            urls.add(ClasspathHelper.forClass(clazz));
        }
        ConfigurationBuilder configBuilder = new ConfigurationBuilder()
                .setScanners(new TypeAnnotationsScanner(), new MethodAnnotationsScanner(), new FieldAnnotationsScanner())
                .setUrls(urls)
                .filterInputsBy(filterBuilder);
        Reflections reflections = new Reflections(configBuilder);
        readSpecs(reflections);
    }

    /**
     * Read documentation from the classes managed by the given classloader.
     * @param classLoader the classloader, not null.
     */
    public void readClasses(ClassLoader classLoader){
        ConfigurationBuilder configBuilder = new ConfigurationBuilder()
                .setScanners(new TypeAnnotationsScanner(), new MethodAnnotationsScanner(), new FieldAnnotationsScanner())
                .setUrls(ClasspathHelper.forClassLoader(classLoader));
        Reflections reflections = new Reflections(configBuilder);
        readSpecs(reflections);
    }

    /**
     * Read documentation from the given packages.
     * @param packages the package names, not null.
     */
    public void readPackages(String... packages) {
        ConfigurationBuilder configBuilder = new ConfigurationBuilder();
        FilterBuilder filterBuilder = new FilterBuilder();
        for (String p : packages) {
            filterBuilder.includePackage(p);
        }
        configBuilder.filterInputsBy(filterBuilder);
        configBuilder.setUrls(ClasspathHelper.forJavaClassPath());
        configBuilder.setScanners(new TypeAnnotationsScanner(), new MethodAnnotationsScanner(), new FieldAnnotationsScanner());
        Reflections reflections = new Reflections(configBuilder);
        readSpecs(reflections);
    }

    /**
     * Access the collected configuration documentation.
     * @return the documentation, not null.
     */
    public DocumentedConfiguration getDocumentation(){
        return docs;
    }

    private void readSpecs(Reflections reflections){
        // types
        for(Class type:reflections.getTypesAnnotatedWith(ConfigSpec.class)){
            readConfigSpec(type);
        }
        for(Class type:reflections.getTypesAnnotatedWith(ConfigAreaSpec.class)){
            readAreaSpec(type);
        }
        for(Class type:reflections.getTypesAnnotatedWith(ConfigAreaSpecs.class)){
            readAreaSpecs(type);
        }
        for(Class type:reflections.getTypesAnnotatedWith(ConfigPropertySpec.class)){
            readPropertySpec(type);
        }
        for(Class type:reflections.getTypesAnnotatedWith(ConfigPropertySpecs.class)){
            readPropertySpecs(type);
        }
        // Fields
        for(Field f:reflections.getFieldsAnnotatedWith(ConfigAreaSpec.class)){
            readAreaSpec(f);
        }
        for(Field f:reflections.getFieldsAnnotatedWith(ConfigAreaSpecs.class)){
            readAreaSpecs(f);
        }
        for(Field f:reflections.getFieldsAnnotatedWith(ConfigPropertySpec.class)){
            readPropertySpec(f);
        }
        for(Field f:reflections.getFieldsAnnotatedWith(ConfigPropertySpecs.class)){
            readPropertySpecs(f);
        }
        // Methods
        for(Method m:reflections.getMethodsAnnotatedWith(ConfigAreaSpec.class)){
            readAreaSpec(m);
        }
        for(Method m:reflections.getMethodsAnnotatedWith(ConfigAreaSpecs.class)){
            readAreaSpecs(m);
        }
        for(Method m:reflections.getMethodsAnnotatedWith(ConfigPropertySpec.class)){
            readPropertySpec(m);
        }
        for(Method m:reflections.getMethodsAnnotatedWith(ConfigPropertySpecs.class)){
            readPropertySpecs(m);
        }
    }

    private void readConfigSpec(Class type){
        docs.init((ConfigSpec)type.getAnnotation(ConfigSpec.class), type);
    }

    private void readAreaSpecs(AnnotatedElement elem){
        ConfigAreaSpecs areaSpecs = elem.getAnnotation(ConfigAreaSpecs.class);
        for (ConfigAreaSpec areaSpec:areaSpecs.value()){
            docs.addGroup(new DocumentedArea(areaSpec, elem));
        }
    }

    private void readPropertySpecs(AnnotatedElement elem){
        ConfigPropertySpecs propertySpecs = elem.getAnnotation(ConfigPropertySpecs.class);
        for (ConfigPropertySpec propertySpec:propertySpecs.value()){
            docs.addProperty(new DocumentedProperty(propertySpec, elem));
        }
    }

    private void readAreaSpec(AnnotatedElement elem){
        docs.addGroup(new DocumentedArea(elem.getAnnotation(ConfigAreaSpec.class), elem));
    }

    private void readPropertySpec(AnnotatedElement elem){
        docs.addProperty(new DocumentedProperty(elem.getAnnotation(ConfigPropertySpec.class), elem));
    }

}
