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

import org.apache.myfaces.extensions.scripting.api.Decorated;
import org.apache.myfaces.extensions.scripting.api.ScriptingConst;
import org.apache.myfaces.extensions.scripting.core.util.WeavingContext;

import javax.el.*;
import javax.faces.FacesException;
import javax.faces.application.Application;
import javax.faces.application.NavigationHandler;
import javax.faces.application.StateManager;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.el.*;
import javax.faces.event.ActionListener;
import javax.faces.validator.Validator;
import java.lang.reflect.Proxy;
import java.util.*;

/**
 * our decorating application
 * which should resolve our bean issues within a central
 * bean processing interceptor
 * <p/>
 *
 * @author Werner Punz
 */
@SuppressWarnings({"deprecation", "deprecation"})
public class ApplicationProxy extends Application implements Decorated {

    volatile Application _delegate;
    volatile static boolean elResolverAdded = false;
    volatile static boolean varResolverAdded = false;

    public ApplicationProxy(Application delegate) {
        _delegate = delegate;
    }

    public void addELResolver(ELResolver elResolver) {
        weaveDelegate();
        /*if (!elResolverAdded) {
            //ordering hints are unsufficient here we make
            //sure our proxy is added as second in the chain
            //also this method works as well on
            //jsf 1.2 while hints only work in jsf2
            elResolver = new ELResolverProxy(elResolver);
            elResolverAdded = true;
        }*/
        _delegate.addELResolver(elResolver);
    }

    private void weaveDelegate() {
        if (_delegate != null) {
            _delegate = (Application) WeavingContext.getWeaver().reloadScriptingInstance(_delegate, ScriptingConst.ARTIFACT_TYPE_APPLICATION);
        }
    }

    public ELResolver getELResolver() {
        weaveDelegate();
        ELResolver retVal = _delegate.getELResolver();
        return retVal;
    }

    //TOD add a weaving for resource bundles

    public ResourceBundle getResourceBundle(FacesContext facesContext, String s) throws FacesException, NullPointerException {
        weaveDelegate();
        return _delegate.getResourceBundle(facesContext, s);
    }

    public UIComponent createComponent(ValueExpression valueExpression, FacesContext facesContext, String s) throws FacesException, NullPointerException {
        weaveDelegate();
        System.out.println("create1");
        UIComponent component = _delegate.createComponent(valueExpression, facesContext, s);

        /*we are reweaving on the fly because we cannot be sure if
         * the class is not recycled all the time in the creation
         * code, in the renderer we do it on method base
         * due to the fact that our renderers are recycled via
         * a flyweight pattern
         *
         *
         * Also we cannot proxy here because there is no UIComponent interface
         * maybe in the long run we can make a decorator here instead
         * but for now lets try it this way
         */
        if (WeavingContext.isDynamic(component.getClass()) && !alreadyWovenInRequest(component.getClass().getName())) {
            /*once it was tainted we have to recreate all the time*/
            component = (UIComponent) WeavingContext.getWeaver().reloadScriptingInstance(component, ScriptingConst.ARTIFACT_TYPE_COMPONENT);
            alreadyWovenInRequest(component.getClass().getName());
        }
        return component;

    }

    public ExpressionFactory getExpressionFactory() {
        weaveDelegate();
        return _delegate.getExpressionFactory();
    }

    public void addELContextListener(ELContextListener elContextListener) {
        weaveDelegate();
        if (WeavingContext.isDynamic(elContextListener.getClass()))
            elContextListener = (ELContextListener) WeavingContext.createMethodReloadingProxyFromObject(elContextListener, ELContextListener.class, ScriptingConst.ARTIFACT_TYPE_ELCONTEXTLISTENER);
        _delegate.addELContextListener(elContextListener);
    }

    public void removeELContextListener(ELContextListener elContextListener) {
        weaveDelegate();
        _delegate.removeELContextListener(elContextListener);
    }

    public ELContextListener[] getELContextListeners() {
        weaveDelegate();
        return _delegate.getELContextListeners();
    }

    public Object evaluateExpressionGet(FacesContext facesContext, String s, Class aClass) throws ELException {
        weaveDelegate();
        //good place for a dynamic reloading check as well
        Object retVal = _delegate.evaluateExpressionGet(facesContext, s, aClass);
        if (WeavingContext.isDynamic(retVal.getClass()))
            retVal = WeavingContext.getWeaver().reloadScriptingInstance(retVal, ScriptingConst.ARTIFACT_TYPE_MANAGEDBEAN);
        return retVal;
    }

    public ActionListener getActionListener() {
        weaveDelegate();
        ActionListener retVal = _delegate.getActionListener();
        if (WeavingContext.isDynamic(retVal.getClass()))
            retVal = (ActionListener) WeavingContext.createMethodReloadingProxyFromObject(retVal, ActionListener.class, ScriptingConst.ARTIFACT_TYPE_ACTIONLISTENER);
        return retVal;
    }

    public void setActionListener(ActionListener actionListener) {
        weaveDelegate();
        if (WeavingContext.isDynamic(actionListener.getClass()))
            actionListener = (ActionListener) WeavingContext.createMethodReloadingProxyFromObject(actionListener, ActionListener.class, ScriptingConst.ARTIFACT_TYPE_ACTIONLISTENER);
        _delegate.setActionListener(actionListener);
    }

    public Locale getDefaultLocale() {
        weaveDelegate();
        return _delegate.getDefaultLocale();
    }

    public void setDefaultLocale(Locale locale) {
        weaveDelegate();
        _delegate.setDefaultLocale(locale);
    }

    public String getDefaultRenderKitId() {
        weaveDelegate();
        return _delegate.getDefaultRenderKitId();
    }

    public void setDefaultRenderKitId(String s) {
        weaveDelegate();
        _delegate.setDefaultRenderKitId(s);
    }

    public String getMessageBundle() {
        weaveDelegate();
        return _delegate.getMessageBundle();
    }

    public void setMessageBundle(String s) {
        weaveDelegate();
        _delegate.setMessageBundle(s);
    }

    public NavigationHandler getNavigationHandler() {
        weaveDelegate();
        //defined in the setter to speed things up a little
        NavigationHandler retVal = _delegate.getNavigationHandler();
        if (retVal != null && WeavingContext.isDynamic(retVal.getClass()))
            retVal = new NavigationHandlerProxy(retVal);
        return retVal;
    }

    public void setNavigationHandler(NavigationHandler navigationHandler) {
        weaveDelegate();
        if (navigationHandler != null && WeavingContext.isDynamic(navigationHandler.getClass()))
            navigationHandler = new NavigationHandlerProxy(navigationHandler);
        _delegate.setNavigationHandler(navigationHandler);
    }

    @SuppressWarnings("deprecation")
    public PropertyResolver getPropertyResolver() {
        weaveDelegate();
        return _delegate.getPropertyResolver();
    }

    @SuppressWarnings("deprecation")
    public void setPropertyResolver(PropertyResolver propertyResolver) {
        weaveDelegate();
        _delegate.setPropertyResolver(propertyResolver);
    }

    @SuppressWarnings("deprecation")
    public VariableResolver getVariableResolver() {
        weaveDelegate();
        VariableResolver variableResolver = _delegate.getVariableResolver();
        return variableResolver;
    }

    @SuppressWarnings("deprecation")
    public void setVariableResolver(VariableResolver variableResolver) {
        weaveDelegate();
        if (!varResolverAdded) {
            variableResolver = new VariableResolverProxy(variableResolver);
            varResolverAdded = true;
        }
        _delegate.setVariableResolver(variableResolver);
    }

    public ViewHandler getViewHandler() {
        weaveDelegate();
        ViewHandler handler = _delegate.getViewHandler();

        /*
        We proxy here to emable dynamic reloading for
        methods in the long run, as soon as we hit
        java all our groovy reloading code is lost
        hence we have to work with proxies here
        */
        if (WeavingContext.isDynamic(handler.getClass()))
            handler = new ViewHandlerProxy(handler);
        return handler;
    }

    public void setViewHandler(ViewHandler viewHandler) {
        weaveDelegate();
        /*make sure you have the delegates as well in properties*/
        if (WeavingContext.isDynamic(viewHandler.getClass()))
            viewHandler = new ViewHandlerProxy(viewHandler);

        _delegate.setViewHandler(viewHandler);
    }

    public StateManager getStateManager() {
        weaveDelegate();
        return _delegate.getStateManager();
    }

    public void setStateManager(StateManager stateManager) {
        weaveDelegate();
        _delegate.setStateManager(stateManager);
    }

    public void addComponent(String componentType, String componentClass) {
        weaveDelegate();
        _delegate.addComponent(componentType, componentClass);
    }

    public UIComponent createComponent(String s) throws FacesException {
        weaveDelegate();
        //the components are generated anew very often
        //we cannot do an on object weaving here
        UIComponent component = _delegate.createComponent(s);

        /*we are reweaving on the fly because we cannot be sure if
        * the class is not recycled all the time in the creation
        * code, in the renderer we do it on method base
        * due to the fact that our renderers are recycled via
        * a flyweight pattern*/
        return (UIComponent) reloadInstance(component, ScriptingConst.ARTIFACT_TYPE_COMPONENT);
    }

    @SuppressWarnings("deprecation")
    public UIComponent createComponent(ValueBinding valueBinding, FacesContext facesContext, String s) throws FacesException {
        weaveDelegate();
        UIComponent component = _delegate.createComponent(valueBinding, facesContext, s);

        /*we are reweaving on the fly because we cannot be sure if
         * the class is not recycled all the time in the creation
         * code, in the renderer we do it on method base
         * due to the fact that our renderers are recycled via
         * a flyweight pattern*/
        return (UIComponent) reloadInstance(component, ScriptingConst.ARTIFACT_TYPE_COMPONENT);
    }

    public Iterator<String> getComponentTypes() {
        weaveDelegate();
        return _delegate.getComponentTypes();
    }

    public void addConverter(String s, String s1) {
        weaveDelegate();
        _delegate.addConverter(s, s1);
    }

    public void addConverter(Class aClass, String s) {
        weaveDelegate();
        _delegate.addConverter(aClass, s);
    }

    public Converter createConverter(String s) {
        weaveDelegate();
        Converter retVal = _delegate.createConverter(s);
        /**
         * since createConverter is called only once
         * we have to work with method reloading proxies
         * we cannot use this technique extensively for speed reasons
         * most of the time it is fine just to work with
         *
         * reloading objects at their interception points
         */
        if (WeavingContext.isDynamic(retVal.getClass())) {
            retVal = (Converter) WeavingContext.createMethodReloadingProxyFromObject(retVal, Converter.class, ScriptingConst.ARTIFACT_TYPE_CONVERTER);

        }

        return retVal;
    }

    public Converter createConverter(Class aClass) {
        weaveDelegate();
        Converter retVal = _delegate.createConverter(aClass);
        if (retVal != null && WeavingContext.isDynamic(retVal.getClass())) {
            retVal = (Converter) WeavingContext.createMethodReloadingProxyFromObject(retVal, Converter.class, ScriptingConst.ARTIFACT_TYPE_CONVERTER);
        }

        return retVal;
    }

    public Iterator<String> getConverterIds() {
        weaveDelegate();
        return _delegate.getConverterIds();
    }

    public Iterator<Class> getConverterTypes() {
        weaveDelegate();
        return _delegate.getConverterTypes();
    }

    @SuppressWarnings("deprecation")
    public MethodBinding createMethodBinding(String s, Class[] classes) throws ReferenceSyntaxException {
        weaveDelegate();
        return _delegate.createMethodBinding(s, classes);
    }

    public Iterator<Locale> getSupportedLocales() {
        weaveDelegate();
        return _delegate.getSupportedLocales();
    }

    public void setSupportedLocales(Collection<Locale> locales) {
        weaveDelegate();
        _delegate.setSupportedLocales(locales);
    }

    public void addValidator(String s, String s1) {
        weaveDelegate();
        _delegate.addValidator(s, s1);
    }

    public Validator createValidator(String s) throws FacesException {
        weaveDelegate();

        Validator retVal = _delegate.createValidator(s);
        if (WeavingContext.isDynamic(retVal.getClass()) && !Proxy.isProxyClass(retVal.getClass())) {
            retVal = (Validator) reloadInstance(retVal, ScriptingConst.ARTIFACT_TYPE_VALIDATOR);
        }
        return retVal;
    }

    public Iterator<String> getValidatorIds() {
        weaveDelegate();
        return _delegate.getValidatorIds();
    }

    @SuppressWarnings("deprecation")
    public ValueBinding createValueBinding(String s) throws ReferenceSyntaxException {
        weaveDelegate();
        return _delegate.createValueBinding(s);
    }

    public Object getDelegate() {
        return _delegate;
    }

    private Object reloadInstance(Object instance, int artefactType) {
        if (instance == null) {
            return null;
        }
        if (WeavingContext.isDynamic(instance.getClass()) && !alreadyWovenInRequest(instance.getClass().getName())) {
            instance = WeavingContext.getWeaver().reloadScriptingInstance(instance, artefactType);
            alreadyWovenInRequest(instance.getClass().getName());
        }
        return instance;
    }

    private boolean alreadyWovenInRequest(String clazz) {
        //portlets now can be enabled thanks to the jsf2 indirections regarding the external context
        Map<String, Object> reqMap = WeavingContext.getRequestMap();
        if (reqMap.get(ScriptingConst.SCRIPTING_REQUSINGLETON + clazz) == null) {
            reqMap.put(ScriptingConst.SCRIPTING_REQUSINGLETON + clazz, "");
            return false;
        }
        return true;
    }

}
