/*
 * 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.view.facelets.tag.composite;

import java.io.IOException;
import java.util.Map;
import javax.faces.component.StateHolder;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;
import javax.faces.event.ComponentSystemEventListener;
import javax.faces.view.facelets.Facelet;
import org.apache.myfaces.config.RuntimeConfig;
import org.apache.myfaces.view.facelets.AbstractFacelet;
import org.apache.myfaces.view.facelets.DynamicComponentRefreshTransientBuildEvent;
import org.apache.myfaces.view.facelets.FaceletCompositionContext;
import org.apache.myfaces.view.facelets.FaceletDynamicComponentRefreshTransientBuildEvent;
import org.apache.myfaces.view.facelets.FaceletFactory;
import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguageBase;
import org.apache.myfaces.view.facelets.LocationAwareFacesException;
import org.apache.myfaces.view.facelets.compiler.RefreshDynamicComponentListener;
import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;

/**
 * This listener must be attached to PostAddToViewEvent, so when composite component is
 * added to the view, the algorithm that create the composite component content is executed.
 *
 * @author lu4242
 */
public class CreateDynamicCompositeComponentListener 
    implements ComponentSystemEventListener, StateHolder
{
    private String taglibURI;
    private String tagName;
    private Map<String,Object> attributes;
    private String baseKey;

    public CreateDynamicCompositeComponentListener(String taglibURI, String tagName, 
        Map<String, Object> attributes, String baseKey)
    {
        this.taglibURI = taglibURI;
        this.tagName = tagName;
        this.attributes = attributes;
        this.baseKey = baseKey;
    }

    public CreateDynamicCompositeComponentListener()
    {
    }
    
    @Override
    public void processEvent(ComponentSystemEvent event)
    {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        
        FaceletViewDeclarationLanguage vdl = (FaceletViewDeclarationLanguage) 
            facesContext.getApplication().getViewHandler().getViewDeclarationLanguage(
                facesContext, facesContext.getViewRoot().getViewId());
        
        Facelet componentFacelet;
        FaceletFactory faceletFactory = vdl.getFaceletFactory();
            
        FaceletFactory.setInstance(faceletFactory);
        try
        {
            componentFacelet
                    = faceletFactory.compileComponentFacelet(taglibURI, tagName, attributes);
        }
        finally
        {
            FaceletFactory.setInstance(null);
        }
        
        UIComponent component = event.getComponent(); 
        // The execution of this listener activated another call to PostAddToViewEvent, because
        // ComponentTagHandlerDelegate removes and add the component again. This is necessary because
        // the inner components also require the propagation of PostAddToViewEvent to refresh themselves.
        // but this check avoids the duplicate call to the facelet, even if the duplicate call does not
        // have any side effect (counts as a refresh).
        Integer step = (Integer) component.getAttributes().get(
            CompositeComponentResourceTagHandler.CREATE_CC_ON_POST_ADD_TO_VIEW); 
        if (step != null && step == 0)
        {
            component.getAttributes().put(CompositeComponentResourceTagHandler.CREATE_CC_ON_POST_ADD_TO_VIEW, 1);
        }
        else
        {
            return;
        }
        try
        {
            facesContext.getAttributes().put(FaceletViewDeclarationLanguage.REFRESHING_TRANSIENT_BUILD,
                Boolean.TRUE);
            
            // Detect the relationship between parent and child, to ensure the component is properly created
            // and refreshed. In facelets this is usually done by core.FacetHandler, but since it is a 
            // dynamic component, we need to do it here before apply the handler
            UIComponent parent = component.getParent();
            String facetName = null;
            if (parent.getFacetCount() > 0 && !parent.getChildren().contains(component))
            {
                facetName = ComponentSupport.findFacetNameByComponentInstance(parent, component);
            }
            
            try
            {
                if (facetName != null)
                {
                    parent.getAttributes().put(org.apache.myfaces.view.facelets.tag.jsf.core.FacetHandler.KEY, 
                            facetName);
                }
                // The trick here is restore MARK_CREATED, just to allow ComponentTagHandlerDelegate to
                // find the component. Then we reset it to exclude it from facelets refresh algorithm.
                String markId = (String) component.getAttributes().get(FaceletViewDeclarationLanguage.GEN_MARK_ID);
                if (markId == null)
                {
                    ((AbstractFacelet) componentFacelet).applyDynamicComponentHandler(
                        facesContext, component, baseKey);
                }
                else
                {
                    try
                    {
                        component.getAttributes().put(ComponentSupport.MARK_CREATED, markId);
                        ((AbstractFacelet) componentFacelet).applyDynamicComponentHandler(
                            facesContext, component.getParent(), baseKey);
                    }
                    finally
                    {
                        component.getAttributes().put(ComponentSupport.MARK_CREATED, null);
                    }
                }
                
                if (FaceletViewDeclarationLanguageBase.isDynamicComponentNeedsRefresh(facesContext))
                {
                    FaceletCompositionContext fcc = FaceletCompositionContext.getCurrentInstance(facesContext);
                    if (fcc == null)
                    {
                        FaceletViewDeclarationLanguageBase.activateDynamicComponentRefreshTransientBuild(facesContext);
                        FaceletViewDeclarationLanguageBase.resetDynamicComponentNeedsRefreshFlag(facesContext);
                        component.subscribeToEvent(DynamicComponentRefreshTransientBuildEvent.class, new 
                            RefreshDynamicComponentListener(taglibURI, tagName, attributes, baseKey));
                        component.getAttributes().put(
                            DynamicComponentRefreshTransientBuildEvent.DYN_COMP_REFRESH_FLAG, Boolean.TRUE);

                    }
                    else
                    {
                        component.subscribeToEvent(FaceletDynamicComponentRefreshTransientBuildEvent.class, new 
                            RefreshDynamicComponentListener(taglibURI, tagName, attributes, baseKey));
                    }
                }
            }
            finally
            {
                if (facetName != null)
                {
                    parent.getAttributes().remove(org.apache.myfaces.view.facelets.tag.jsf.core.FacetHandler.KEY);
                }
            }
        }
        catch (IOException e)
        {
            throw new LocationAwareFacesException(e, component);
        }
        finally
        {
            facesContext.getAttributes().remove(FaceletViewDeclarationLanguage.REFRESHING_TRANSIENT_BUILD);
        }
    }

    @Override
    public Object saveState(FacesContext context)
    {
        RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(context.getExternalContext());
        Object[] values = new Object[4];
        Integer tagId = runtimeConfig.getIdByNamespace().get(taglibURI);
        if (tagId != null)
        {
            values[0] = tagId;
        }
        else if (taglibURI.startsWith(CompositeResourceLibrary.NAMESPACE_PREFIX))
        {
            values[0] = new Object[]{0, taglibURI.substring(35)};
        }
        else if(taglibURI.startsWith(CompositeResourceLibrary.ALIAS_NAMESPACE_PREFIX))
        {
            values[0] = new Object[]{1, taglibURI.substring(34)};
        }
        else
        {
            values[0] = taglibURI;
        }
        values[1] = tagName;
        values[2] = attributes;
        values[3] = baseKey;
        return values;
    }

    @Override
    public void restoreState(FacesContext context, Object state)
    {
        Object[] values = (Object[]) state;
        if (values[0] instanceof String)
        {
            taglibURI = (String) values[0];
        }
        else if (values[0] instanceof Integer)
        {
            RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(context.getExternalContext());
            taglibURI = runtimeConfig.getNamespaceById().get((Integer)values[0]);
        }
        else if (values[0] instanceof Object[])
        {
            Object[] def = (Object[])values[0];
            String ns = (((Integer) def[0]) == 0) ? 
                CompositeResourceLibrary.NAMESPACE_PREFIX :
                CompositeResourceLibrary.ALIAS_NAMESPACE_PREFIX;
            taglibURI = ns + (String) ((Object[]) values[0])[1];
        }
        tagName = (String)values[1];
        attributes = (Map<String,Object>) values[2];
        baseKey = (String)values[3];
    }

    @Override
    public boolean isTransient()
    {
        return false;
    }

    @Override
    public void setTransient(boolean newTransientValue)
    {
    }

}
