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

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ComponentMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.Model;
import org.apache.myfaces.buildtools.maven2.plugin.builder.utils.BuildException;
import org.apache.myfaces.buildtools.maven2.plugin.builder.utils.MyfacesUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.runtime.RuntimeConstants;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;

import com.thoughtworks.qdox.JavaDocBuilder;
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;

/**
 * Maven goal to generate java source code for Component classes.
 * 
 * <p>It uses velocity to generate templates, and has the option to define custom templates.</p>
 * <p>The executed template has the following variables available to it:</p>
 * <ul>
 *  <li>utils : Returns an instance of 
 *  org.apache.myfaces.buildtools.maven2.plugin.builder.utils.MyfacesUtils, 
 *  it contains some useful methods.</li>
 *  <li>component : Returns the current instance of
 *   org.apache.myfaces.buildtools.maven2.plugin.builder.model.ComponentMeta</li>
 *  <li>innersource : code to be injected from the template class when template
 *  mode is used</li>  
 * </ul>
 * 
 * @version $Id$
 * @requiresDependencyResolution compile
 * @goal make-components
 * @phase generate-sources
 */
public class MakeComponentsMojo extends AbstractMojo
{
    final Logger log = Logger.getLogger(MakeComponentsMojo.class.getName());

    /**
     * Injected Maven project.
     * 
     * @parameter expression="${project}"
     * @readonly
     */
    private MavenProject project;

    /**
     * Defines the directory where the metadata file (META-INF/myfaces-metadata.xml) is loaded.
     * 
     * @parameter expression="${project.build.directory}/myfaces-builder-plugin/main/resources"
     * @readonly
     */
    private File buildDirectory;

    /**
     * Injected name of file generated by earlier run of BuildMetaDataMojo goal.
     * 
     * @parameter
     */
    private String metadataFile = "META-INF/myfaces-metadata.xml";

    /**
     * The directory used to load templates into velocity environment.
     * 
     * @parameter expression="src/main/resources/META-INF"
     */
    private File templateSourceDirectory;

    /**
     * The directory where all generated files are created. This directory is added as a
     * compile source root automatically like src/main/java is. 
     * 
     * @parameter expression="${project.build.directory}/myfaces-builder-plugin/main/java"
     */
    private File generatedSourceDirectory;

    /**
     * Generate only component classes that starts with the specified package prefix. 
     * 
     * @parameter
     */
    private String packageContains;

    /**
     * Generate only component classes that starts with the specified component type prefix. 
     * 
     * @parameter
     */
    private String typePrefix;

    /**
     *  Log and continue execution when generating component classes.
     *  <p>
     *  If this property is set to false (default), errors when a component class is generated stops
     *  execution immediately.
     *  </p>
     * 
     * @parameter
     */
    private boolean force;

    /**
     * Defines the jsf version (1.1 or 1.2), used to take the default templates for each version.
     * <p> 
     * If version is 1.1, the default templateComponentName is 'componentClass11.vm' and if version
     * is 1.2 the default templateComponentName is 'componentClass12.vm'.
     * </p>
     * 
     * @parameter
     */
    private String jsfVersion;
    
    /**
     * Define the models that should be included when generate component classes. If not set, the
     * current model identified by the artifactId is used.
     * <p>
     * Each model built by build-metadata goal has a modelId, that by default is the artifactId of
     * the project. Setting this property defines which objects tied in a specified modelId should
     * be taken into account.  
     * </p>
     * <p>In this case, limit component generation only to the components defined in the models 
     * identified by the modelId defined. </p>
     * <p>This is useful when you need to generate files that take information defined on other
     * projects</p>
     * <p>Example:</p>
     * <pre>
     *    &lt;modelIds&gt;
     *        &lt;modelId>model1&lt;/modelId&gt;
     *        &lt;modelId>model2&lt;/modelId&gt;
     *    &lt;/modelIds&gt;
     * </pre>
     * 
     * @parameter
     */
    private List modelIds;

    /**
     * The name of the template used to generate component classes. According to the value on 
     * jsfVersion property the default if this property is not set could be componentClass11.vm (1.1) or
     * componentClass12.vm (1.2)
     * 
     * @parameter 
     */
    private String templateComponentName;
    
    /**
     * This param is used to search in this folder if some file to
     * be generated exists and avoid generation and duplicate exception.
     * 
     * @parameter expression="src/main/java"
     */    
    private File mainSourceDirectory;
    
    /**
     * This param is used to search in this folder if some file to
     * be generated exists and avoid generation and duplicate exception.
     * 
     * @parameter
     */        
    private File mainSourceDirectory2;

    /**
     * Execute the Mojo.
     */
    public void execute() throws MojoExecutionException
    {
        // This command makes Maven compile the generated source:
        // getProject().addCompileSourceRoot( absoluteGeneratedPath.getPath() );
        
        try
        {
            project.addCompileSourceRoot( generatedSourceDirectory.getCanonicalPath() );
            
            if (modelIds == null)
            {
                modelIds = new ArrayList();
                modelIds.add(project.getArtifactId());
            }
            Model model = IOUtils.loadModel(new File(buildDirectory,
                    metadataFile));
            new Flattener(model).flatten();
            generateComponents(model);
        }
        catch (IOException e)
        {
            throw new MojoExecutionException("Error generating components", e);
        }
        catch (BuildException e)
        {
            throw new MojoExecutionException("Error generating components", e);
        }
    }
    
    
    private VelocityEngine initVelocity() throws MojoExecutionException
    {

        Properties p = new Properties();

        p.setProperty( "resource.loader", "file, class" );
        p.setProperty( "file.resource.loader.class",
                "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
        p.setProperty( "file.resource.loader.path", templateSourceDirectory.getPath());
        p.setProperty( "class.resource.loader.class",
                "org.apache.myfaces.buildtools.maven2.plugin.builder.utils.RelativeClasspathResourceLoader" );
        p.setProperty( "class.resource.loader.path", "META-INF");            
        p.setProperty( "velocimacro.library", "componentClassMacros11.vm");
        p.setProperty( "velocimacro.permissions.allow.inline","true");
        p.setProperty( "velocimacro.permissions.allow.inline.local.scope", "true");
        p.setProperty( "directive.foreach.counter.initial.value","0");
        p.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
        "org.apache.myfaces.buildtools.maven2.plugin.builder.utils.ConsoleLogSystem" );
        
        File template = new File(templateSourceDirectory, _getTemplateName());
        
        if (template.exists())
        {
            log.info("Using template from file loader: "+template.getPath());
        }
        else
        {
            log.info("Using template from class loader: META-INF/"+_getTemplateName());
        }
                
        VelocityEngine velocityEngine = new VelocityEngine();
                
        try
        {
            velocityEngine.init(p);
        }
        catch (Exception e)
        {
            throw new MojoExecutionException("Error creating VelocityEngine", e);
        }
        
        return velocityEngine;
    }
    

    /**
     * Generates parsed components.
     */
    private void generateComponents(Model model) throws IOException,
            MojoExecutionException
    {
        // Make sure generated source directory 
        // is added to compilation source path 
        //project.addCompileSourceRoot(generatedSourceDirectory.getCanonicalPath());
        
        //Init Qdox for extract code 
        JavaDocBuilder builder = new JavaDocBuilder();
        
        List sourceDirs = project.getCompileSourceRoots();
        
        // need a File object representing the original source tree
        for (Iterator i = sourceDirs.iterator(); i.hasNext();)
        {
            String srcDir = (String) i.next();
            builder.addSourceTree(new File(srcDir));
        }        
        
        //Init velocity
        VelocityEngine velocityEngine = initVelocity();

        VelocityContext baseContext = new VelocityContext();
        baseContext.put("utils", new MyfacesUtils());
        
        for (Iterator it = model.getComponents().iterator(); it.hasNext();)
        {
            ComponentMeta component = (ComponentMeta) it.next();
            
            if (component.getClassName() != null)
            {
                File f = new File(mainSourceDirectory, StringUtils.replace(
                    component.getClassName(), ".", "/")+".java");
                                
                if (!f.exists() && canGenerateComponent(component))
                {
                    if (mainSourceDirectory2 != null)
                    {
                        File f2 = new File(mainSourceDirectory2, StringUtils.replace(
                                component.getClassName(), ".", "/")+".java");
                        if (f2.exists())
                        {
                            //Skip
                            continue;
                        }
                    }
                    log.info("Generating component class:"+component.getClassName());
                    
                    try 
                    {
                        _generateComponent(velocityEngine, builder,component,baseContext);
                    }
                    catch(MojoExecutionException e)
                    {
                        if (force)
                        {
                            log.severe(e.getMessage());
                        }
                        else
                        {
                            //Stop execution throwing exception
                            throw e;
                        }
                    }
                }
            }
        }        
    }
    
    public boolean canGenerateComponent(ComponentMeta component)
    {
        if ( modelIds.contains(component.getModelId())
                && includePackage(component)
                && includeType(component))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    public boolean includePackage(ComponentMeta component)
    {
        if (packageContains != null)
        {
            if (MyfacesUtils.getPackageFromFullClass(component.getClassName()).startsWith(packageContains))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return true;
        }        
    }

    public boolean includeType(ComponentMeta component)
    {
        if (typePrefix != null)
        {
            if (component.getType().startsWith(typePrefix))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return true;
        }        
    }
    
    
    /**
     * Generates a parsed component.
     * 
     * @param component
     *            the parsed component metadata
     */
    private void _generateComponent(VelocityEngine velocityEngine,
            JavaDocBuilder builder,
            ComponentMeta component, VelocityContext baseContext)
            throws MojoExecutionException
    {
        Context context = new VelocityContext(baseContext);
        context.put("component", component);

        if (Boolean.TRUE.equals(component.isTemplate()))
        {
            String source = this.getInnerSourceCode(builder, component);
            
            if (source != null && !"".equals(source))
            {
                context.put("innersource", source);
            }
        }        
        
        Writer writer = null;
        File outFile = null;

        try
        {
            outFile = new File(generatedSourceDirectory, StringUtils.replace(
                    component.getClassName(), ".", "/")+".java");

            if ( !outFile.getParentFile().exists() )
            {
                outFile.getParentFile().mkdirs();
            }

            writer = new OutputStreamWriter(new FileOutputStream(outFile));

            Template template = velocityEngine.getTemplate(_getTemplateName());
                        
            template.merge(context, writer);

            writer.flush();
        }
        catch (Exception e)
        {
            throw new MojoExecutionException(
                    "Error merging velocity templates: " + e.getMessage(), e);
        }
        finally
        {
            IOUtil.close(writer);
            writer = null;
        }
    }
        
    /**
     * This method extract from component scanned sourceClass, the parts
     * which we need to move to generated class as a single String using Qdox.
     * 
     * Ignore code that has a \@JSFExclude or \@JSFProperty Doclet or Annotation
     * 
     * @param component
     * @return
     */
    private String getInnerSourceCode(JavaDocBuilder builder, ComponentMeta component)
    {   
        StringWriter writer = new StringWriter();
        
        JavaClass sourceClass = builder.getClassByName(component.getSourceClassName());
        
        JavaField [] fields = sourceClass.getFields();

        //Include the fields defined
        for (int i = 0; i < fields.length; i++)
        {            
            JavaField field = fields[i];
            
            DocletTag tag = field.getTagByName("JSFExclude");
            Annotation anno = getAnnotation(field, "JSFExclude");
            
            if (!(tag == null && anno == null))
            {
                continue;
            }
                        
            if (!isExcludedField(field.getName()))
            {
                writer.append("    ");
                writer.append(field.getDeclarationSignature(true));
                String initExpr = field.getInitializationExpression();
                initExpr = cleanInitializationExpression(initExpr);
                if (initExpr != null)
                {
                    writer.append(" = ");
                    writer.append(initExpr);
                }                
                writer.append(';');
                writer.append('\n');
            }
        }
        
        JavaMethod [] methods = sourceClass.getMethods();
        for (int i = 0; i < methods.length; i++)
        {
            JavaMethod method = methods[i];

            DocletTag tag = method.getTagByName("JSFExclude");
            Annotation anno = getAnnotation(method, "JSFExclude");
            
            if (!(tag == null && anno == null))
            {
                continue;
            }
            
            tag = method.getTagByName("JSFProperty", false);
            anno = getAnnotation(method, "JSFProperty");
            
            if ( (tag == null && anno == null) || !method.isAbstract())
            {              
                //Get declaration signature in a way that we don't need
                //to declare imports.
                String declaration = method.getDeclarationSignature(true);
                                
                writer.append("    ");
                writer.append(declaration);
                String sourceCode = method.getSourceCode();
                if(sourceCode != null && sourceCode.length() > 0)
                {
                    writer.append('\n');
                    writer.append("    ");
                    writer.append('{');
                    writer.append(method.getSourceCode());
                    writer.append('}');
                    writer.append('\n');
                    writer.append('\n');
                }
                else
                {
                    writer.append(';');
                    writer.append('\n');
                }
            }
            
        }
                
        return writer.toString();
    }
    
    private boolean isExcludedField(String name)
    {
        return (name.equals("COMPONENT_TYPE") || 
                name.equals("DEFAULT_RENDERER_TYPE") ||
                name.equals("COMPONENT_FAMILY") );
    }

    /**
     * Clean up a field initialisation expression returned by qdox.
     * <p>
     * When a class has "int foo = 1;" then the initialisation expression
     * is the bit after the equals sign. Unfortunately qdox tends to return
     * a lot of garbage stuff in there. In particular, if there is no
     * initialisation expression, then qdox can return a string with
     * whitespace (not a null or empty string). 
     * <p>
     * In addition, if there are comments *before* a field declaration,
     * they appear inside the initialisation text (this is just broken
     * behaviour in qdox). Ideally we would move them to above the field
     * declaration where they belong. However that is complicated and
     * fragile, so we just discard them here.
     */
    static String cleanInitializationExpression(String expr)
    {
        expr = StringUtils.trim(expr);
        if (StringUtils.isEmpty(expr))
        {
            return null;
        }
        
        // split on linefeeds
        // trim each separately
        // remove any comment chars
        
        if (expr.contains("\n"))
        {
            StringBuffer buf = new StringBuffer(100);
            String[] lines = StringUtils.split(expr, "\n");
            for(int i=0; i<lines.length; ++i)
            {
                String line = lines[i];
                line = StringUtils.trim(line);
                if (!line.startsWith("//") && !StringUtils.isEmpty(line))
                {
                    if (buf.length()> 0)
                    {
                        buf.append(" ");
                    }
                    buf.append(line);
                }
            }
            
            expr = buf.toString();
        }
        
        if (expr.startsWith("//"))
        {
            return null;
        }

        if (StringUtils.isEmpty(expr))
        {
            return null;
        }

        return expr;
    }

    /**
     * TODO: Copied from QdoxModelBuilder!
     * 
     * @param entity
     * @param annoName
     * @return
     */
    private Annotation getAnnotation(AbstractJavaEntity entity, String annoName)
    {
        Annotation[] annos = entity.getAnnotations();
        if (annos == null)
        {
            return null;
        }
        // String wanted = ANNOTATION_BASE + "." + annoName;
        for (int i = 0; i < annos.length; ++i)
        {
            Annotation thisAnno = annos[i];
            // Ideally, here we would check whether the fully-qualified name of
            // the annotation
            // class matches ANNOTATION_BASE + "." + annoName. However it
            // appears that qdox 1.6.3
            // does not correctly expand @Foo using the class import statements;
            // method
            // Annotation.getType.getJavaClass.getFullyQualifiedName still just
            // returns the short
            // class name. So for now, just check for the short name.
            String thisAnnoName = thisAnno.getType().getJavaClass().getName();
            
            //Make short name for recognizing, if returns long
            int containsPoint = thisAnnoName.lastIndexOf('.');
            if (containsPoint != -1)
            {
                thisAnnoName = thisAnnoName.substring(containsPoint+1);
            }
            if (thisAnnoName.equals(annoName))
            {
                return thisAnno;
            }
        }
        return null;
    }    

    private String _getTemplateName()
    {
        if (templateComponentName == null)
        {
            if (_is12())
            {
                return "componentClass12.vm";
            }
            else
            {
                return "componentClass11.vm";
            }
        }
        else
        {
            return templateComponentName;
        }
    }
    
    private boolean _is12()
    {
        return "1.2".equals(jsfVersion) || "12".equals(jsfVersion);
    }

}
