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

import org.apache.myfaces.config.RuntimeConfig;
import org.apache.myfaces.config.element.NavigationRule;
import org.apache.myfaces.config.impl.digester.elements.ManagedBean;
import org.apache.myfaces.extensions.scripting.core.api.AnnotationScanListener;
import org.apache.myfaces.extensions.scripting.core.common.util.ReflectUtil;
import org.apache.myfaces.extensions.scripting.core.common.util.StringUtils;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.CustomScoped;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.NoneScoped;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;

/**
 * bean implementation listener which registers new java sources
 * into the runtime config, note this class is not thread safe
 * it is only allowed to be called from a single thread
 *
 * @author Werner Punz (latest modification by $Author$)
 * @version $Revision$ $Date$
 */

public class MyFacesBeanImplementationListener extends BaseAnnotationScanListener implements AnnotationScanListener
{

    public boolean supportsAnnotation(String annotation) {
        return annotation.equals(javax.faces.bean.ManagedBean.class.getName());
    }

    public boolean supportsAnnotation(Class annotation) {
        return annotation.equals(javax.faces.bean.ManagedBean.class);
    }

    public void register(Class clazz, java.lang.annotation.Annotation ann) {


        javax.faces.bean.ManagedBean annCasted = (javax.faces.bean.ManagedBean) ann;

        String beanName = annCasted.name();
        if (StringUtils.isBlank(beanName)) {
            beanName = normalizeName(clazz.getName());
        }

        beanName = beanName.replaceAll("\"", "");
        //we need to reregister for every bean due to possible managed prop
        //and scope changes
        registerManagedBean(clazz, beanName);

    }

    /**
     * registers a new managed bean into runtime config
     * @param clazz
     * @param beanName
     */
    protected void registerManagedBean(Class clazz, String beanName)
    {
        RuntimeConfig config = getRuntimeConfig();

        ManagedBean mbean;
        if (!hasToReregister(beanName, clazz)) {
            mbean = (ManagedBean) _alreadyRegistered.get(beanName);
            //return;
        } else {
            mbean = new ManagedBean();
        }

        mbean.setBeanClass(clazz.getName());

        ReflectUtil.setField(mbean, "beanClass", null, true);
        mbean.setName(beanName);
        handleManagedpropertiesCompiled(mbean, fields(clazz));
        resolveScope(clazz, mbean);

        _alreadyRegistered.put(beanName, mbean);
        config.addManagedBean(beanName, mbean);
    }

    private void resolveScope(Class clazz, ManagedBean mbean) {
        //now lets resolve the scope
        String scope = "none";
        if (clazz.isAnnotationPresent(RequestScoped.class)) {
            scope = "request";
        } else if (clazz.isAnnotationPresent(SessionScoped.class)) {
            scope = "session";
        } else if (clazz.isAnnotationPresent(ApplicationScoped.class)) {
            scope = "application";
        } else if (clazz.isAnnotationPresent(ViewScoped.class)) {
            scope = "view";    
        } else if (clazz.isAnnotationPresent(NoneScoped.class)) {
            scope = "none";
        } else if (clazz.isAnnotationPresent(CustomScoped.class)) {
            CustomScoped customScoped = (CustomScoped) clazz.getAnnotation(CustomScoped.class);
            scope = (customScoped != null) ? customScoped.value() : "custom";
        }
        mbean.setScope(scope);
    }

    protected void handleManagedpropertiesCompiled(ManagedBean mbean, Field[] fields) {
        /*since we reprocess the managed properties we can handle them here by clearing them first*/
        mbean.getManagedProperties().clear();
        for (Field field : fields) {
            if (_log.isLoggable(Level.FINEST)) {
                _log.log(Level.FINEST, "  Scanning field '" + field.getName() + "'");
            }
            ManagedProperty property = field
                    .getAnnotation(ManagedProperty.class);
            if (property != null) {
                if (_log.isLoggable(Level.FINE)) {
                    _log.log(Level.FINE, "  Field '" + field.getName()
                            + "' has a @ManagedProperty annotation");
                }

                org.apache.myfaces.config.impl.digester.elements.ManagedProperty mpc =
                        new org.apache.myfaces.config.impl.digester.elements.ManagedProperty();
                String name = property.name();
                if ((name == null) || "".equals(name)) {
                    name = field.getName();
                }
                mpc.setPropertyName(name);
                mpc.setPropertyClass(field.getType().getName()); // FIXME - primitives, arrays, etc.
                mpc.setValue(property.value());

                ReflectUtil.executeMethod(mbean, "addProperty", mpc);
            }
        }
    }

    /**
     * <p>Return an array of all <code>Field</code>s reflecting declared
     * fields in this class, or in any superclass other than
     * <code>java.lang.Object</code>.</p>
     *
     * @param clazz Class to be analyzed
     * @return the array of fields
     */
    private Field[] fields(Class clazz) {

        Map<String, Field> fields = new HashMap<String, Field>();
        do {
            for (Field field : clazz.getDeclaredFields()) {
                if (!fields.containsKey(field.getName())) {
                    fields.put(field.getName(), field);
                }
            }
        } while ((clazz = clazz.getSuperclass()) != Object.class);
        return fields.values().toArray(new Field[fields.size()]);
    }

    protected boolean hasToReregister(String name, Class clazz) {
        ManagedBean mbean = (ManagedBean) _alreadyRegistered.get(name);
        return mbean == null || !mbean.getManagedBeanClassName().equals(clazz.getName());
    }

    /**
     * name normalizer for automated name mapping
     * (aka if no name attribute is given in the annotation)
     *
     * @param className the classname to be mapped (can be with package=
     * @return the normalized jsf bean name
     */
    private String normalizeName(String className) {
        String name = className.substring(className.lastIndexOf(".") + 1);

        return name.substring(0, 1).toLowerCase() + name.substring(1);
    }

    @SuppressWarnings("unchecked")
    public void purge(String className) {
        RuntimeConfig config = getRuntimeConfig();
        //We have to purge and readd our managed beans, unfortunatly the myfaces impl enforces
        //us to do the same for the nav rules after purge
        //we cannot purge the managed beans and nav rules separately
        Collection<NavigationRule> navigationRules = new ArrayList<NavigationRule>();
        Map managedBeans = new HashMap<String, org.apache.myfaces.config.element.ManagedBean>();

        navigationRules.addAll(config.getNavigationRules());
        managedBeans.putAll(config.getManagedBeans());

        config.purge();

        for (NavigationRule navRule : navigationRules) {
            config.addNavigationRule(navRule);
        }

        //We refresh the managed beans, dead references still can cause
        //runtime errors but in this case we cannot do anything
        org.apache.myfaces.config.element.ManagedBean mbeanFound = null;
        List<String> mbeanKey = new LinkedList<String>();

        for (Object entry : managedBeans.entrySet()) {
            Map.Entry mbean = (Map.Entry) entry;

            Object bean =  mbean.getValue();


            if (!((Class)ReflectUtil.executeMethod( bean, "getManagedBeanClass")).getName().equals(className)) {
                config.addManagedBean((String) mbean.getKey(), (org.apache.myfaces.config.element.ManagedBean) mbean.getValue());
            } else {
                Object mbeanf = mbean.getValue();
                mbeanKey.add((String)ReflectUtil.executeMethod(mbeanf, "getManagedBeanName"));
            }
        }
        if (mbeanFound != null) {
            for (String toRemove : mbeanKey) {
                _alreadyRegistered.remove(toRemove);
            }
        }
    }

    protected RuntimeConfig getRuntimeConfig() {
        final FacesContext facesContext = FacesContext.getCurrentInstance();
        //runtime config not started
        if (facesContext == null) {
            return null;
        }
        return RuntimeConfig.getCurrentInstance(facesContext.getExternalContext());
    }
}
