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

import org.apache.myfaces.config.RuntimeConfig;
import org.apache.myfaces.config.annotation.LifecycleProvider;
import org.apache.myfaces.config.annotation.LifecycleProviderFactory;
import org.apache.myfaces.config.element.ManagedBean;
import org.apache.myfaces.config.element.ManagedProperty;
import org.apache.myfaces.extensions.scripting.core.util.ReflectUtil;
import org.apache.myfaces.extensions.scripting.core.util.WeavingContext;
import org.apache.myfaces.extensions.scripting.monitor.ClassResource;
import org.apache.myfaces.extensions.scripting.monitor.RefreshContext;
import org.apache.myfaces.extensions.scripting.monitor.RefreshAttribute;
import org.apache.myfaces.util.ContainerUtils;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.faces.context.FacesContext;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Bean handler implementation
 * which encapsulates the myfaces specific parts
 * of the bean processing
 */
public class MyFacesBeanHandler implements BeanHandler {

    final Logger _logger = Logger.getLogger(MyFacesBeanHandler.class.getName());

    /**
     * scripting engine for this bean handler
     */
    int _scriptingEngine;

    /**
     * constructor
     *
     * @param scriptingEngine the scripting engine the bean handler
     *                        currently has to attach to for its
     *                        operations
     */
    public MyFacesBeanHandler(int scriptingEngine) {
        this._scriptingEngine = scriptingEngine;
    }

    /**
     * scans all bean dependencies according to
     * their IoC information stored by the runtime
     * (in our case the MyFaces runtime confing)
     * and adds those into our backward referencing dependency map
     * to add further dependency information on IoC level
     * (we can have IoC dependencies which are bound by object
     * types, this is a corner case but it still can happen)
     */
    public void scanDependencies() {

    }

    /**
     * scans the dependencies on el level
     * Not working out for now
     */
  /*  public void scanElDependencies() {
        Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
        for(Map.Entry<String, ManagedBean> entry: mbeans.entrySet()) {
            Object bean = entry.getValue();
            if(bean instanceof org.apache.myfaces.config.impl.digester.elements.ManagedBean) {
                org.apache.myfaces.config.impl.digester.elements.ManagedBean workBean = (org.apache.myfaces.config.impl.digester.elements.ManagedBean) bean;

                Object props = ReflectUtil.executeMethod(workBean,"getManagedProperties");
                if(props instanceof Iterator) {
                    //myfaces 1.2
                } else {
                    for(ManagedProperty prop: ((Collection<ManagedProperty>) props)) {
                          ExpressionFactory expFactory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
                          ELContext elContext = FacesContext.getCurrentInstance().getELContext();
                           expFactory.coerceToType("#{myFactory['booga']}");   
                          //if(ContainerUtils.isValueReference((String) prop.getV))
                          elContext.getELResolver().getType(elContext,"myFactory","booga");
                    }
                }


            }
            //Iterator<ManagedProperty> it = bean.getManagedProperties();
            //we rescan all managed props to cover pure object
            //references as well as class references
            //while(it.hasNext()) {
            //    ManagedProperty prop = it.next();
            //}
        }
    } */

    /**
     * Refreshes all managed beans
     * session, and personal scoped ones
     * <p/>
     * personal scoped beans are beans which
     * have either
     * <li> session scope </li>
     * <li> page scope </li>
     * <li> custom scope </li>
     */
    public void refreshAllManagedBeans() {
        if (FacesContext.getCurrentInstance() == null) {
            return;//no npe allowed
        }

        Set<String> tainted = getTaintedClasses();

        //scanElDependencies();

        if (tainted.size() > 0) {
            //We now have to check if the tainted classes belong to the managed beans
            Set<String> managedBeanClasses = new HashSet<String>();

            Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
            Map<String, ManagedBean> mbeansSnapshotView;

            synchronized (RefreshContext.BEAN_SYNC_MONITOR) {
                mbeansSnapshotView = makeSnapshot(mbeans);
            }
            for (Map.Entry<String, ManagedBean> entry : mbeansSnapshotView.entrySet()) {
                managedBeanClasses.add(entry.getValue().getManagedBeanClassName());
            }

            boolean managedBeanTainted = isAnyManagedBeanTainted(tainted, managedBeanClasses);
            markPersonalScopeRefreshRecommended();
            getLog().info("[EXT-SCRIPTING] Tainting all beans to avoid classcast exceptions");
            if (managedBeanTainted) {
                globalManagedBeanRefresh(mbeansSnapshotView);
                //personalScopeRefresh();
            }
        }
    }

    /**
     * Exposed personal scope refresh
     */
    public void personalScopeRefresh() {
        //shortcut to avoid heavier operations in the beginning
        long globalBeanRefreshTimeout = WeavingContext.getRefreshContext().getPersonalScopedBeanRefresh();
        if (globalBeanRefreshTimeout == -1l) return;

        Map sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
        Long timeOut = (Long) sessionMap.get(ScriptingConst.SESS_BEAN_REFRESH_TIMER);
        if (timeOut == null || timeOut <= globalBeanRefreshTimeout) {
            refreshPersonalScopedBeans();
        }
    }

    /**
     * removes all bean references which have been tainted
     * (note for now we remove all dynamic references until we
     * get a more sophisticated handling of managed beans)
     *
     * @param workCopy the managed beam snapshot view
     */
    private void globalManagedBeanRefresh(Map<String, ManagedBean> workCopy) {
        Set<String> tainted = getTaintedClasses();

        for (Map.Entry<String, ManagedBean> entry : workCopy.entrySet()) {
            Class managedBeanClass = entry.getValue().getManagedBeanClass();
            if (hasToBeRefreshed(tainted, managedBeanClass)) {
                //managed bean class found we drop the class from our session
                removeBeanReferences(entry.getValue());
            }
            //one bean tainted we have to taint all dynamic beans otherwise we will get classcast
            //exceptions
            /*getLog().info("[EXT-SCRIPTING] Tainting ");
            RefreshAttribute metaData = WeavingContext.getFileChangedDaemon().getClassMap().get(managedBeanClass.getName());
            if (metaData != null) {
                metaData.requestRefresh();
            }*/
        }
    }

    /**
     * determines whether any bean in our managed bean list
     * is tainted or not
     *
     * @param tainted            a list of classes which are tainted in this iteration
     * @param managedBeanClasses a ist of classes which are our managed beans
     * @return true if one of the beans is tainted
     */
    private boolean isAnyManagedBeanTainted(Set<String> tainted, Set<String> managedBeanClasses) {
        boolean managedBeanTainted = false;
        for (String taintedClass : tainted) {
            if (managedBeanClasses.contains(taintedClass)) {
                managedBeanTainted = true;
                break;
            }
        }
        return managedBeanTainted;
    }

    /**
     * helper which returns all tainted classes
     *
     * @return the tainted classes
     */
    private Set<String> getTaintedClasses() {
        Set<String> tainted = new HashSet<String>();

        for (Map.Entry<String, ClassResource> it : WeavingContext.getFileChangedDaemon().getClassMap().entrySet()) {
            if (it.getValue().getScriptingEngine() == getScriptingEngine() && it.getValue().getRefreshAttribute().requiresRefresh()) {
                tainted.add(it.getKey());
            }
        }
        return tainted;
    }

    /**
     * refreshes all personal scoped beans (aka beans which
     * have an assumed lifecycle <= session)
     * <p/>
     * This is needed for multiuser purposes because if one user alters some beans
     * other users have to drop their non application scoped beans as well!
     */
    private void refreshPersonalScopedBeans() {
        //the refreshing is only allowed if no compile is in progress
        //and vice versa
        Map sessionMap = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
        Long taintingPeriod = (Long) sessionMap.get(ScriptingConst.SESS_BEAN_REFRESH_TIMER);
        if (taintingPeriod == null) {
            taintingPeriod = -1l;
        }
        Set<String> taintedInTime = WeavingContext.getRefreshContext().getTaintHistoryClasses(taintingPeriod);

        synchronized (RefreshContext.BEAN_SYNC_MONITOR) {
            Map<String, ManagedBean> mbeans = RuntimeConfig.getCurrentInstance(FacesContext.getCurrentInstance().getExternalContext()).getManagedBeans();
            //the map is immutable but in between scanning might change it so we make a full copy of the map

            //We can synchronized the refresh, but if someone alters
            //the bean map from outside we still get race conditions
            //But for most cases this mutex should be enough
            Map<String, ManagedBean> mbeansSnapshotView = makeSnapshot(mbeans);

            for (Map.Entry<String, ManagedBean> entry : mbeansSnapshotView.entrySet()) {
                Class managedBeanClass = entry.getValue().getManagedBeanClass();
                if (hasToBeRefreshed(taintedInTime, managedBeanClass)) {
                    FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(entry.getValue().getManagedBeanName());
                    removeCustomScopedBean(entry.getValue());
                }
            }
            updateBeanRefreshTime();
        }
    }

    /**
     * removes the references from out static scope
     * for jsf2 we probably have some kind of notification mechanism
     * which notifies custom scopes
     *
     * @param bean the managed bean which all references have to be removed from
     */

    private void removeBeanReferences(ManagedBean bean) {
        if (getLog().isLoggable(Level.FINE)) {
            getLog().log(Level.FINE, "[EXT-SCRIPTING] JavaScriptingWeaver.removeBeanReferences({0})", bean.getManagedBeanName());
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(bean.getManagedBeanName());
        FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().remove(bean.getManagedBeanName());
        removeCustomScopedBean(bean);
    }

    /**
     * @return the log for this class
     */
    protected Logger getLog() {
        return Logger.getLogger(this.getClass().getName());
    }

    /**
     * jsf2 helper to remove custom scoped beans
     *
     * @param bean the managed bean which has to be removed from the custom scope from
     */
    private void removeCustomScopedBean(ManagedBean bean) {
        Object scopeImpl = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().get(bean.getManagedBeanScope());
        if (scopeImpl == null) return; //scope not implemented
        //we now have to revert to introspection here because scopes are a pure jsf2 construct
        //so we use a messaging pattern here to cope with it

        Object beanInstance = ReflectUtil.executeMethod(scopeImpl, "get", bean.getManagedBeanName());
        LifecycleProvider lifecycleProvider =
                LifecycleProviderFactory.getLifecycleProviderFactory().getLifecycleProvider(FacesContext.getCurrentInstance().getExternalContext());
        try {
            lifecycleProvider.destroyInstance(beanInstance);
        } catch (IllegalAccessException e) {
            _logger.log(Level.WARNING, "removeCustomScopedBean():", e);
        } catch (InvocationTargetException e) {
            _logger.log(Level.WARNING, "removeCustomScopedBean():", e);
        }
    }

    /**
     * MyFaces 2.0 keeps an immutable map over the session
     * and request scoped beans
     * if we alter that during our loop we get a concurrent modification exception
     * taking a snapshot in time fixes that
     *
     * @param mbeans the internal managed bean map which has to be investigated
     * @return a map with the class name as key and the managed bean info
     *         as value of the current state of the internal runtime config bean map
     */
    private Map<String, ManagedBean> makeSnapshot(Map<String, ManagedBean> mbeans) {
        Map<String, ManagedBean> workCopy;

        workCopy = new HashMap<String, ManagedBean>(mbeans.size());
        for (Map.Entry<String, ManagedBean> entry : mbeans.entrySet()) {
            workCopy.put(entry.getKey(), entry.getValue());
        }

        return workCopy;
    }

    /**
     * updates the internal timer
     * for our personal scoped beans so that
     * we dont get updates on beans we have refreshed already
     */
    private void updateBeanRefreshTime() {
        long sessionRefreshTime = System.currentTimeMillis();
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(ScriptingConst.SESS_BEAN_REFRESH_TIMER, sessionRefreshTime);
    }

    /**
     * sets the internal timer for other processes
     * to update their beans as well
     */
    private void markPersonalScopeRefreshRecommended() {
        long sessionRefreshTime = System.currentTimeMillis();
        WeavingContext.getRefreshContext().setPersonalScopedBeanRefresh(sessionRefreshTime);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(ScriptingConst.SESS_BEAN_REFRESH_TIMER, sessionRefreshTime);
    }

    /**
     * important, this method determines whether a managed bean class
     * has to be refreshed or not
     *
     * @param tainted          set of tainted classes
     * @param managedBeanClass the class to be checked for refresh criteria
     * @return true if the current bean class fulfills our refresh criteria
     */
    protected boolean hasToBeRefreshed(Set<String> tainted, Class managedBeanClass) {

        return WeavingContext.isDynamic(managedBeanClass) && tainted.contains(managedBeanClass.getName());
    }

    /**
     * returns the scripting engine which is attached
     * to this bean handler
     *
     * @return the current scripting engine
     */
    private int getScriptingEngine() {
        return _scriptingEngine;
    }
}
