/*
 *  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.buildtools.maven2.plugin.builder.qdox.parse;

import java.util.Map;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ComponentMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.FacetHolder;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.FacetMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ListenerHolder;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ListenerMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.Model;
import org.apache.myfaces.buildtools.maven2.plugin.builder.qdox.QdoxHelper;

import com.thoughtworks.qdox.model.AbstractJavaEntity;
import com.thoughtworks.qdox.model.Annotation;
import com.thoughtworks.qdox.model.DocletTag;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.Type;

/**
 * 
 * @author Leonardo Uribe
 * @since 1.0.9
 *
 */
public class ComponentParsingStrategy extends ClassMetaPropertyParsingStrategy
{
    private static final String DOC_FACET = "JSFFacet";
    private static final String DOC_LISTENER = "JSFListener";

    public void parseClass(JavaClass clazz, Model model)
    {
        DocletTag tag;
        Annotation anno;
        // components
        tag = clazz.getTagByName(DOC_COMPONENT, false);
        if (tag != null)
        {
            Map props = tag.getNamedParameterMap();
            processComponent(props, (AbstractJavaEntity)tag.getContext(), clazz, model);
        }
        anno = QdoxHelper.getAnnotation(clazz, DOC_COMPONENT);
        if (anno != null)
        {
            Map props = anno.getNamedParameterMap();
            processComponent(props, (AbstractJavaEntity)anno.getContext(), clazz, model);
        }
    }

    private void processComponent(Map props, AbstractJavaEntity ctx,
            JavaClass clazz, Model model)
    {
        String componentTypeDflt = null;
        JavaField fieldComponentType = clazz.getFieldByName("COMPONENT_TYPE");
        if (fieldComponentType != null)
        {
            componentTypeDflt = QdoxHelper.clean(fieldComponentType
                    .getInitializationExpression());
        }

        String componentTypeFamily = null;
        JavaField fieldComponentFamily = clazz
                .getFieldByName("COMPONENT_FAMILY");
        if (fieldComponentFamily != null)
        {
            componentTypeFamily = QdoxHelper.clean(fieldComponentFamily
                    .getInitializationExpression());
        }

        String rendererTypeDflt = null;
        JavaField fieldRendererType = clazz
                .getFieldByName("DEFAULT_RENDERER_TYPE");
        if (fieldRendererType != null)
        {
            rendererTypeDflt = QdoxHelper.clean(fieldRendererType
                    .getInitializationExpression());
        }

        String componentName = QdoxHelper.getString(clazz, "name", props, null);

        // Check for both "class" and "clazz" in order to support
        // doclet and real annotations.
        String classNameOverride = QdoxHelper.getString(clazz, "class", props, null);
        classNameOverride = QdoxHelper.getString(clazz,"clazz",props,classNameOverride);
                
        Boolean template = QdoxHelper.getBoolean(clazz,"template",props, null);
                
        String longDescription = clazz.getComment();
        String descDflt = QdoxHelper.getFirstSentence(longDescription);
        if ((descDflt == null) || (descDflt.length() < 2))
        {
            descDflt = "no description";
        }
        String shortDescription = QdoxHelper.getString(clazz, "desc", props, descDflt);

        String bodyContent = QdoxHelper.getString(clazz, "bodyContent", props, null);
        
        String componentFamily = QdoxHelper.getString(clazz, "family", props,
                componentTypeFamily);
        String componentType = QdoxHelper.getString(clazz, "type", props,
                componentTypeDflt);
        String rendererType = QdoxHelper.getString(clazz, "defaultRendererType", props,
                rendererTypeDflt);
        Boolean canHaveChildren = QdoxHelper.getBoolean(clazz, "canHaveChildren", props, null);
        Boolean configExcluded = QdoxHelper.getBoolean(clazz,"configExcluded",props,null);        

        String tagClass = QdoxHelper.getString(clazz, "tagClass", props, null);
        String tagSuperclass = QdoxHelper.getString(clazz, "tagSuperclass", props, null);
        String tagHandler = QdoxHelper.getString(clazz, "tagHandler", props, null);
        String defaultEventName = QdoxHelper.getString(clazz, "defaultEventName", props, null);
        String serialuid = QdoxHelper.getString(clazz, "serialuid", props, null);
        String implementsValue = QdoxHelper.getString(clazz, "implements", props, null);
        implementsValue = QdoxHelper.getString(clazz, "implementz", props, implementsValue);
        
        Boolean composite = QdoxHelper.getBoolean(clazz, "composite", props, null);

        ComponentMeta component = new ComponentMeta();
        initClassMeta(model, clazz, component, classNameOverride);
        component.setName(componentName);
        component.setBodyContent(bodyContent);
        component.setDescription(shortDescription);
        component.setLongDescription(longDescription);
        component.setConfigExcluded(configExcluded);
        component.setType(componentType);
        component.setFamily(componentFamily);
        component.setRendererType(rendererType);
        component.setChildren(canHaveChildren);
        component.setSerialuid(serialuid);
        component.setImplements(implementsValue);
        component.setTemplate(template);
        component.setDefaultEventName(defaultEventName);
        if (defaultEventName != null)
        {
            component.setOverrideDefaultEventName(Boolean.TRUE);
        }
        JavaClass[] interfaces = clazz.getImplementedInterfaces();
        for (int i = 0; i < interfaces.length; ++i)
        {
            JavaClass iface = interfaces[i];
            if (iface.getFullyQualifiedName().equals(
                    "javax.faces.component.NamingContainer"))
            {
                component.setNamingContainer(Boolean.TRUE);
                break;
            }
            if (iface.getFullyQualifiedName().equals(
                    "javax.faces.component.behavior.ClientBehaviorHolder"))
            {
                component.setClientBehaviorHolder(Boolean.TRUE);
                break;
            }
            if (!(template != null && template.booleanValue()))
            {
                component.addImplementedInterfaceClassName(
                        QdoxHelper.getFullyQualifiedClassName(iface, iface.getFullyQualifiedName()));
            }
        }
        if (implementsValue != null)
        {
            if (StringUtils.contains(implementsValue, "javax.faces.component.behavior.ClientBehaviorHolder"))
            {
                component.setClientBehaviorHolder(Boolean.TRUE);
            }
            StringTokenizer st = new StringTokenizer(implementsValue,",");
            while (st.hasMoreTokens())
            {
                component.addImplementedInterfaceClassName(st.nextToken());
            }
        }
        component.setTagClass(tagClass);
        component.setTagSuperclass(tagSuperclass);
        component.setTagHandler(tagHandler);
        component.setComposite(composite);

        // Now here walk the component looking for property annotations.
        processComponentProperties(clazz, component);
        processComponentFacets(clazz, component);
        processComponentListeners(clazz, component);

        model.addComponent(component);
    }
    
    private void processComponentFacets(JavaClass clazz,
            FacetHolder component)
    {
        JavaMethod[] methods = clazz.getMethods();
        for (int i = 0; i < methods.length; ++i)
        {
            JavaMethod method = methods[i];

            DocletTag tag = method.getTagByName(DOC_FACET);
            if (tag != null)
            {
                Map props = tag.getNamedParameterMap();
                processComponentFacet(props, (AbstractJavaEntity)tag.getContext(), clazz,
                        method, component);
            }

            Annotation anno = QdoxHelper.getAnnotation(method, DOC_FACET);
            if (anno != null)
            {
                Map props = anno.getNamedParameterMap();
                processComponentFacet(props, (AbstractJavaEntity)anno.getContext(), clazz,
                        method, component);
            }
        }
        
        Type [] interfaces = clazz.getImplements();
        
        //Scan interfaces for properties to be added to this component
        //This feature allow us to have groups of functions.
        for (int i = 0; i < interfaces.length;++i)
        {
            JavaClass intf = interfaces[i].getJavaClass();

            //If the interfaces has a JSFComponent Doclet,
            //this is managed in other way
            if (intf.getTagByName(DOC_COMPONENT, false) == null)
            {
                JavaMethod[] intfmethods = intf.getMethods();
                for (int j = 0; j < intfmethods.length; ++j)
                {
                    JavaMethod intfmethod = intfmethods[j];

                    DocletTag tag = intfmethod.getTagByName(DOC_FACET);
                    if (tag != null)
                    {
                        Map props = tag.getNamedParameterMap();
                        processInterfaceComponentFacet(props, (AbstractJavaEntity)tag.getContext(), 
                                clazz, intfmethod, component);
                    }

                    Annotation anno = QdoxHelper.getAnnotation(intfmethod, DOC_FACET);
                    if (anno != null)
                    {
                        Map props = anno.getNamedParameterMap();
                        processInterfaceComponentFacet(props, (AbstractJavaEntity)anno.getContext(),
                                clazz, intfmethod, component);
                    }
                }
            }
        }
    }
    
    private void processInterfaceComponentFacet(Map props, AbstractJavaEntity ctx,
            JavaClass clazz, JavaMethod method, FacetHolder component)
    {
        this.processComponentFacet(props, ctx, clazz, method, component);
                
        FacetMeta facet = component.getFacet(QdoxHelper.methodToPropName(method.getName()));
                
        //Try to get the method from the component clazz to see if this
        //has an implementation
        JavaMethod clazzMethod = clazz.getMethodBySignature(method.getName(), null , false);
                
        if (clazzMethod == null)
        {
            //The method should be generated!
            facet.setGenerated(Boolean.TRUE);
        }            
    }
    
    private void processInterfaceComponentListener(Map props, AbstractJavaEntity ctx,
            JavaClass clazz, JavaMethod method, ListenerHolder component)
    {
        this.processComponentListener(props, ctx, clazz, method, component);
                
        ListenerMeta listener = component.getListener(QdoxHelper.methodToPropName(method.getName()));
                
        //Try to get the method from the component clazz to see if this
        //has an implementation
        JavaMethod clazzMethod = clazz.getMethodBySignature(method.getName(), null , false);
                
        if (clazzMethod == null)
        {
            //The method should be generated!
            listener.setGenerated(Boolean.TRUE);
        }            
    }

    private void processComponentListeners(JavaClass clazz,
            ListenerHolder component)
    {
        JavaMethod[] methods = clazz.getMethods();
        for (int i = 0; i < methods.length; ++i)
        {
            JavaMethod method = methods[i];

            DocletTag tag = method.getTagByName(DOC_LISTENER);
            if (tag != null)
            {
                Map props = tag.getNamedParameterMap();
                processComponentListener(props, (AbstractJavaEntity)tag.getContext(), clazz,
                        method, component);
            }

            Annotation anno = QdoxHelper.getAnnotation(method, DOC_LISTENER);
            if (anno != null)
            {
                Map props = anno.getNamedParameterMap();
                processComponentListener(props, (AbstractJavaEntity)anno.getContext(), clazz,
                        method, component);
            }
        }
        
        Type [] interfaces = clazz.getImplements();
        
        //Scan interfaces for properties to be added to this component
        //This feature allow us to have groups of functions.
        for (int i = 0; i < interfaces.length;++i)
        {
            JavaClass intf = interfaces[i].getJavaClass();

            //If the interfaces has a JSFComponent Doclet,
            //this is managed in other way
            if (intf.getTagByName(DOC_COMPONENT, false) == null)
            {
                JavaMethod[] intfmethods = intf.getMethods();
                for (int j = 0; j < intfmethods.length; ++j)
                {
                    JavaMethod intfmethod = intfmethods[j];

                    DocletTag tag = intfmethod.getTagByName(DOC_LISTENER);
                    if (tag != null)
                    {
                        Map props = tag.getNamedParameterMap();
                        processInterfaceComponentListener(props, (AbstractJavaEntity)tag.getContext(), 
                                clazz, intfmethod, component);
                    }

                    Annotation anno = QdoxHelper.getAnnotation(intfmethod, DOC_LISTENER);
                    if (anno != null)
                    {
                        Map props = anno.getNamedParameterMap();
                        processInterfaceComponentListener(props, (AbstractJavaEntity)anno.getContext(),
                                clazz, intfmethod, component);
                    }
                }
            }
        }
    }
    
    private void processComponentFacet(Map props, AbstractJavaEntity ctx,
            JavaClass clazz, JavaMethod method, FacetHolder component)
    {
        Boolean required = QdoxHelper.getBoolean(clazz, "required", props, null);

        String longDescription = ctx.getComment();
        String descDflt = QdoxHelper.getFirstSentence(longDescription);
        if ((descDflt == null) || (descDflt.length() < 2))
        {
            descDflt = "no description";
        }
        String shortDescription = QdoxHelper.getString(clazz, "desc", props, descDflt);
        
        FacetMeta p = new FacetMeta();
        p.setName(QdoxHelper.methodToPropName(method.getName()));
        p.setRequired(required);
        p.setDescription(shortDescription);
        p.setLongDescription(longDescription);
        
        //If the method is abstract this should be generated
        if (method.isAbstract())
        {
            p.setGenerated(Boolean.TRUE);
        }

        component.addFacet(p);
    }
    
    private void processComponentListener(Map props, AbstractJavaEntity ctx,
            JavaClass clazz, JavaMethod method, ListenerHolder component)
    {
        Boolean required = QdoxHelper.getBoolean(clazz, "required", props, null);

        String longDescription = ctx.getComment();
        String descDflt = QdoxHelper.getFirstSentence(longDescription);
        if ((descDflt == null) || (descDflt.length() < 2))
        {
            descDflt = "no description";
        }
        String shortDescription = QdoxHelper.getString(clazz, "desc", props, descDflt);
        
        Type returnType = null;
        
        if (method.getName().startsWith("set"))
        {
            returnType = method.getParameters()[0].getType();
        }
        else
        {
            returnType = method.getReturns();
        }
        
        String fullyQualifiedReturnType = returnType.getJavaClass().getFullyQualifiedName();
        fullyQualifiedReturnType = QdoxHelper.getFullyQualifiedClassName(clazz, fullyQualifiedReturnType);
        fullyQualifiedReturnType = QdoxHelper.getString(clazz, "clazz", props, fullyQualifiedReturnType);
        
        String phases = QdoxHelper.getString(clazz, "phases", props, null);
        String eventClassName = QdoxHelper.getString(clazz, "event", props, null);
        String name = QdoxHelper.getString(clazz, "name", props, QdoxHelper.methodToPropName(method.getName()));
        
        ListenerMeta p = new ListenerMeta();
        p.setName(name);
        p.setClassName(fullyQualifiedReturnType);
        p.setEventClassName(eventClassName);
        p.setRequired(required);
        p.setDescription(shortDescription);
        p.setLongDescription(longDescription);
        p.setPhases(phases);
        
        //If the method is abstract this should be generated
        if (method.isAbstract())
        {
            p.setGenerated(Boolean.TRUE);
        }

        component.addListener(p);
    }
}
