/*
 * 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 javax.faces.component;

import org.apache.myfaces.core.api.shared.lang.ClassUtils;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.el.ValueExpression;
import javax.faces.FactoryFinder;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.render.RenderKit;
import javax.faces.render.RenderKitFactory;
import javax.faces.render.Renderer;

import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
import org.apache.myfaces.core.api.shared.MessageUtils;

/**
 * 
 * TODO: documentation on jsp and pld are not the same. It appear two
 * params: maxlength and for, but no property getter and setter founded here. 
 * If maxlength is used, we can put something like this: 
 * JSFJspProperty(name = "maxlength", returnType = "java.lang.String")
 * 
 * @since 2.0
 */
@JSFComponent(name = "f:viewParam", bodyContent = "JSP", 
        tagClass = "org.apache.myfaces.taglib.core.ViewParamTag")
@JSFJspProperty(name = "maxlength", returnType = "int",
                longDesc = "The max number or characters allowed for this param")
public class UIViewParameter extends UIInput
{
    private static final Logger log = Logger.getLogger(UIViewParameter.class.getName());
    public static final String COMPONENT_FAMILY = "javax.faces.ViewParameter";
    public static final String COMPONENT_TYPE = "javax.faces.ViewParameter";

    private static final String DELEGATE_FAMILY = UIInput.COMPONENT_FAMILY;
    private static final String DELEGATE_RENDERER_TYPE = "javax.faces.Text";
    
    private static ConcurrentHashMap<ClassLoader,Renderer> delegateRendererMap = 
        new ConcurrentHashMap<ClassLoader,Renderer>();

    public UIViewParameter()
    {
        setRendererType(null);
    }

    @Override
    public String getFamily()
    {
        return COMPONENT_FAMILY;
    }

    @Override
    public void decode(FacesContext context)
    {
        // Override behavior from superclass to pull a value from the incoming request parameter map under the 
        // name given by getName() and store it with a call to UIInput.setSubmittedValue(java.lang.Object).
        String value = context.getExternalContext().getRequestParameterMap().get(getName());
        
        // only apply the value if it is non-null (otherwise postbacks 
        // to a view with view parameters would not work correctly)
        if (value != null)
        {
            setSubmittedValue(value);
        }
    }

    @Override
    public void encodeAll(FacesContext context) throws IOException
    {
        if (context == null) 
        {
            throw new NullPointerException();
        }
        setSubmittedValue(getStringValue(context));
    }

    public String getName()
    {
        return (String) getStateHelper().eval(PropertyKeys.name);
    }

    public String getStringValue(FacesContext context)
    {
        if (getValueExpression ("value") != null) 
        {
            // Value specified as an expression, so do the conversion.
            
            return getStringValueFromModel (context);
        }
        
        // Otherwise, just return the local value.
        return ((String) this.getLocalValue());
    }

    public String getStringValueFromModel(FacesContext context) throws ConverterException
    {
        ValueExpression ve = getValueExpression ("value");
        Converter converter;
        Object value;
        
        if (ve == null) 
        {
            // No value expression, return null.
            return null;
        }
        
        value = ve.getValue (context.getELContext());
        
        if (value instanceof String) 
        {
            // No need to convert.
            return ((String) value);
        }
        
        converter = getConverter();
        
        if (converter == null) 
        {
            if (value == null) 
            {
                // No converter, no value, return null.
                return null;
            }
            
            // See if we can create the converter from the value type.
            
            converter = context.getApplication().createConverter (value.getClass());
            
            if (converter == null) 
            {
                // Only option is to call toString().
                
                return value.toString();
            }
        }
        
        return converter.getAsString (context, this, value);
    }

    @JSFProperty(tagExcluded=true)
    @Override
    public boolean isImmediate()
    {
        return false;
    }
    
    @JSFProperty(tagExcluded=true)
    @Override
    public boolean isRendered()
    {
        return super.isRendered();
    }
    
    @Override
    public void processValidators(FacesContext context)
    {
        if (context == null) 
        {
            throw new NullPointerException ("context");
        }
        
        // If value is null and required is set, validation fails.
        
        if ((getSubmittedValue() == null) && isRequired()) 
        {
            FacesMessage message;
            String required = getRequiredMessage();
            
            if (required != null) 
            {
                message = new FacesMessage (FacesMessage.SEVERITY_ERROR, required, required);
            }
            else 
            {
                Object label = MessageUtils.getLabel(context, this);
                
                message = MessageUtils.getMessage(context, context.getViewRoot().getLocale(),
                     FacesMessage.SEVERITY_ERROR, REQUIRED_MESSAGE_ID, new Object[] { label });
            }
            
            setValid (false);
            
            context.addMessage (getClientId (context), message);
            context.validationFailed();
            context.renderResponse();
            
            return;
        }
        
        super.processValidators (context);
    }
    
    enum PropertyKeys
    {
        name
    }
    
    public void setName(String name)
    {
        getStateHelper().put(PropertyKeys.name, name );
    }

    @Override
    public void updateModel(FacesContext context)
    {
        super.updateModel(context);
        
        // Put name in request map if value is not a value expression, is valid, and local
        // value was set.
        
        if ((getValueExpression ("value") == null) && isValid() && isLocalValueSet()) 
        {
            context.getExternalContext().getRequestMap().put(getName(), getLocalValue());
        }
    }

    @Override
    protected Object getConvertedValue(FacesContext context, Object submittedValue) throws ConverterException
    {
        return getDelegateRenderer(context).getConvertedValue(context, this, submittedValue);
    }

    private static Renderer getDelegateRenderer(FacesContext context)
    {
        ClassLoader classLoader = ClassUtils.getContextClassLoader();
        Renderer delegateRenderer = delegateRendererMap.get(classLoader);
        if(delegateRenderer == null)
        {
            RenderKitFactory factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
            RenderKit kit = factory.getRenderKit(context, RenderKitFactory.HTML_BASIC_RENDER_KIT);

            delegateRenderer = kit.getRenderer(DELEGATE_FAMILY, DELEGATE_RENDERER_TYPE);
            delegateRendererMap.put(classLoader, delegateRenderer);
        }

        return delegateRenderer;
    }

    /**
     * The idea of this method is to be called from AbstractFacesInitializer (impl code).
     */
    @SuppressWarnings("unused")
    private static void releaseRenderer() 
    {
        if (log.isLoggable(Level.FINEST))
        {
            log.finest("releaseRenderer rendererMap -> " + delegateRendererMap.toString());
        }

        ClassLoader classLoader = ClassUtils.getContextClassLoader();
        
        if (log.isLoggable(Level.FINEST))
        {
            log.finest("releaseRenderer classLoader -> " + classLoader.toString() );
            log.finest("releaseRenderer renderer -> " + delegateRendererMap.get(classLoader));
        }
        
        delegateRendererMap.remove(classLoader);
        
        if (log.isLoggable(Level.FINEST))
        {
            log.finest("releaseRenderer renderMap -> " + delegateRendererMap.toString());
        }
        
    }

    @Override
    protected FacesContext getFacesContext()
    {
        //In theory the parent most of the times has 
        //the cached FacesContext instance, because this
        //element is purely logical, and the parent is the one
        //where encodeXXX was invoked. But only limit the
        //search to the closest parent.
        UIComponent parent = getParent();
        if (parent != null && parent.isCachedFacesContext())
        {
            return parent.getFacesContext();
        }
        else
        {
            return super.getFacesContext();
        }
    }

    /**
     * @since 2.0
     */
    public static class Reference
    {
        private int _index;
        private UIViewParameter _param;
        private Object _state;
        private String _viewId;

        public Reference(FacesContext context, UIViewParameter param, int indexInParent,
                         String viewIdAtTimeOfConstruction)
        {
            // This constructor cause the StateHolder.saveState(javax.faces.context.FacesContext) method
            // to be called on argument UIViewParameter.
            _param = param;
            _viewId = viewIdAtTimeOfConstruction;
            _index = indexInParent;
            _state = param.saveState(context);
        }

        public UIViewParameter getUIViewParameter(FacesContext context)
        {
            // If the current viewId is the same as the viewId passed to our constructor
            if (context.getViewRoot().getViewId().equals(_viewId))
            {
                // use the index passed to the constructor to find the actual UIViewParameter instance and return it.
                // FIXME: How safe is that when dealing with component trees altered by applications?
                return (UIViewParameter) _param.getParent().getChildren().get(_index);
            }
            else
            {
                // Otherwise, call StateHolder.restoreState(javax.faces.context.FacesContext, java.lang.Object) on
                // the saved state and return the result.
                _param.restoreState(context, _state);

                return _param;
            }
        }
    }
}
