/*
 * 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.myfaces.extensions.scripting.jsf2.annotation;

import org.apache.myfaces.extensions.scripting.api.*;
import org.apache.myfaces.extensions.scripting.core.util.WeavingContext;
import org.apache.myfaces.extensions.scripting.loaders.java.ScannerClassloader;
import org.apache.myfaces.extensions.scripting.monitor.ClassResource;
import org.apache.myfaces.extensions.scripting.monitor.RefreshAttribute;

import javax.faces.context.FacesContext;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Werner Punz (latest modification by $Author$)
 * @version $Revision$ $Date$
 *          <p/>
 *          Source path annotation scanner for java it scans all sources in the specified source paths
 *          recursively for additional information
 *          and then adds the id/name -> class binding information to the correct factory locations,
 *          wherever possible
 */
@SuppressWarnings("unused")
public class GenericAnnotationScanner extends BaseAnnotationScanListener implements ClassScanner {

    List<ClassScanListener> _listeners = new LinkedList<ClassScanListener>();

    Map<String, String> _registeredAnnotations = new HashMap<String, String>();
    LinkedList<String> _sourcePaths = new LinkedList<String>();

    ScriptingWeaver _weaver = null;

    public GenericAnnotationScanner() {
        initDefaultListeners();
    }

    public GenericAnnotationScanner(ScriptingWeaver weaver) {
        _weaver = weaver;
        initDefaultListeners();
    }

    public void addScanPath(String sourcePath) {
        _sourcePaths.addFirst(sourcePath);
    }

    Collection<java.lang.annotation.Annotation> filterAnnotations(java.lang.annotation.Annotation[] annotations) {
        List<java.lang.annotation.Annotation> retVal = new ArrayList<java.lang.annotation.Annotation>(annotations.length);
        
        for (java.lang.annotation.Annotation annotation : annotations) {
            if (annotation.annotationType().getName().startsWith(ScriptingConst.JAVAX_FACES)) {
                retVal.add(annotation);
            }

        }
        return retVal;
    }

    public void scanClass(Class clazz) {
        java.lang.annotation.Annotation[] annotations = clazz.getAnnotations();

        Collection<java.lang.annotation.Annotation> annCol = filterAnnotations(annotations);
        if (!annCol.isEmpty()) {
            addOrMoveAnnotations(clazz);
        } else {
            removeAnnotations(clazz);
        }
    }

    private void initDefaultListeners() {
        _listeners.add(new BeanImplementationListener());
        _listeners.add(new BehaviorImplementationListener());
        _listeners.add(new ComponentImplementationListener());
        _listeners.add(new ConverterImplementationListener());
        _listeners.add(new RendererImplementationListener());
        _listeners.add(new ValidatorImplementationListener());
    }

    /**
     * builds up the parsing chain and then notifies its observers
     * on the found data
     */
    public void scanPaths() {
        //https://issues.apache.org/jira/browse/EXTSCRIPT-33

        //check if the faces config is already available otherwise we cannot scan yet
        final FacesContext facesContext = FacesContext.getCurrentInstance();
        //runtime config not started
        //for now we only can reach the runtime config in the referenced BaseAnnotatonScanListener
        //if we have a facesContext reachable.
        if (facesContext == null) {
            //TODO (1.1) decouple the scan in the BaseAnnotationScanListener from the facesConfig
            //to get the runtime config
            return;
        }

        for (String className : _weaver.loadPossibleDynamicClasses()) {
            try {
                ScannerClassloader loader = new ScannerClassloader(Thread.currentThread().getContextClassLoader(), -1, null, WeavingContext.getConfiguration().getCompileTarget());

                Class clazz;
                //in case the class does not exist we have to load it from our weavingcontext
                //otherwise we do just a scan on the class to avoid side behavior
                if (WeavingContext.getFileChangedDaemon().getClassMap().get(className) == null) {
                    clazz = _weaver.loadScriptingClassFromName(className);
                } else {
                    clazz = loader.loadClass(className);
                }

                if (clazz != null) {
                    java.lang.annotation.Annotation[] anns = clazz.getAnnotations();
                    if (anns != null && anns.length > 0) {
                        addOrMoveAnnotations(clazz);
                    } else {
                        removeAnnotations(clazz);
                    }
                }
            } catch (ClassNotFoundException e) {
                Logger _logger = Logger.getLogger(this.getClass().getName());
                _logger.log(Level.WARNING, "", e);
            }
        }

    }

    /**
     * add or moves a class level annotation
     * to a new place
     *
     * @param clazz the class to have the annotation moved or added
     */
    private void addOrMoveAnnotations(Class clazz) {
        java.lang.annotation.Annotation[] anns = clazz.getAnnotations();
        for (java.lang.annotation.Annotation ann : anns) {
            for (ClassScanListener cListener : _listeners) {
                AnnotationScanListener listener = (AnnotationScanListener) cListener;
                if (listener.supportsAnnotation(ann.annotationType())) {
                    listener.register(clazz, ann);

                    _registeredAnnotations.put(clazz.getName(), ann.annotationType().getName());
                    //TODO check if we still need this
                    ClassResource metaData = WeavingContext.getFileChangedDaemon().getClassMap().get(clazz.getName());
                    
                }
            }
        }
    }

    /**
     * use case annotation removed
     * we have to entirely remove the annotation
     * from our internal registry and the myfaces registry
     *
     * @param clazz the class to have the annotation removed
     */
    private void removeAnnotations(Class clazz) {
        String registeredAnnotation = _registeredAnnotations.get(clazz.getName());
        if (registeredAnnotation != null) {
            for (ClassScanListener cListener : _listeners) {
                AnnotationScanListener listener = (AnnotationScanListener) cListener;
                if (listener.supportsAnnotation(registeredAnnotation)) {
                    listener.purge(clazz.getName());
                    _registeredAnnotations.remove(clazz.getName());
                    WeavingContext.getFileChangedDaemon().getClassMap().remove(clazz.getName());
                }
            }
        }
    }

    public void clearListeners() {
        _listeners.clear();
    }

    public void addListener(ClassScanListener listener) {
        _listeners.add(listener);
    }

    @Override
    public void scanAndMarkChange() {
        //do nothing here
    }
}
