/*
 *  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.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

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.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.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.RuntimeConstants;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.Xpp3DomWriter;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * Creates taglib (tld) and faces-config files.
 * <p>
 * This Mojo actually provides a generic goal that will run a configurable
 * velocity template file and generate a single output file. The template is
 * passed the full metadata model object, and can select from the model whatever
 * data it wants.
 * </p>
 * <p>
 * The execution can be configured with:
 * <ul>
 * <li>The name of the input template to be executed</li>
 * <li>The name of the output file to be created</li>
 * <li>Any number of variables which are accessable from the template
 * (string values only)</li>
 * </ul>
 * </p>
 * <p>
 * The executed template has the following variables available to it:
 * <ul>
 * <li>model: the full metadata model for this project</li>
 * <li>modelIds: specifies which items from the model should be processed</li>
 * <li>baseContent: the full text of the contents of the "xmlBaseFile" (if any)</li>
 * <li>utils: an instance of MyfacesUtils that provides static helper methods</li>
 * <li>and whatever (name,value) pairs were configured via the "params" property
 * of this mojo.</li>
 * </ul>
 * </p>
 * 
 * @requiresDependencyResolution compile
 * @goal make-config
 * @phase generate-sources
 */
public class MakeConfigMojo extends AbstractMojo
{
    /**
     * The current maven project (auto-injected by Maven).
     * 
     * @parameter expression="${project}"
     * @readonly
     */
    private MavenProject project;

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

    /**
     * Name of the file from which the metadata model passed to the
     * template will be read. This file is typically generated by an earlier
     * execution of the BuildMetaDataMojo goal for the same maven project.
     * 
     * @parameter
     */
    private String metadataFile = "META-INF/myfaces-metadata.xml";

    /**
     * Specifies the name of the output file to be created.
     * 
     * @parameter
     */
    private String xmlFile = "META-INF/faces-config.xml";
    
    /**
     * A list of metadata model ids.
     * <p>
     * If not defined, then this defaults to a list containing just one string whose
     * value is the same as the current maven project's artifactId.
     * </p>
     * <p>
     * The complete metadata model is passed to the velocity template. This contains 
     * data about not just the model items defined in the calling project, but also
     * about items imported from other projects. Each item in the model is
     * labelled with a "model id" indicating which project it was defined by.
     * </p>
     * <p>
     * This list of model ids is also passed to the template. The template can
     * then use that data to select the relevant items from the full model.
     * </p>
     * 
     * @parameter
     */
    private List modelIds;
            
    /**
     * The base directory used when resolving references to external files from
     * velocity #include and #parse commands within the executed template.
     * 
     * @parameter expression="src/main/resources/META-INF"
     */
    private File templateSourceDirectory;
    
    /**
     * When defined, specifies an xml file whose top-level elements are to be copied
     * directly into the created file.
     * <p>
     * This allows a hand-written file to be created containing data that cannot be
     * automatically generated. All content beneath the root element of the specified
     * file (but not the root element itself) is placed into a Velocity variable
     * named "baseContent" that the template can reference.
     * </p>
     * <p>
     * The template can do whatever it wants with this variable, but it is expected
     * that the template will simply output this immediately after writing the
     * root element of the output xml file.
     * file.
     * </p>
     * <p>
     * Note that any attributes or namespaces defined on the root element of the
     * xmlBaseFile are ignored.
     * </p>
     * 
     * @parameter expression="src/main/conf/META-INF/faces-config-base.xml"
     */    
    private File xmlBaseFile;

    /**
     * Specifies the Velocity template file to be executed.
     * 
     * @parameter expression="faces-config11.vm"
     */
    private String templateFile;
    
    /**
     * A map of (name, value) pairs to be made available as Velocity variables
     * for the executed template to access.
     * 
     * @parameter
     */
    private Map params;
        
    /**
     * Execute the Mojo.
     * <p>
     * The metadata model is loaded, and the specified template is executed with
     * any template output being written to the specified output file.
     * </p>
     */
    public void execute() throws MojoExecutionException
    {
        try
        {
            if (modelIds == null)
            {
                modelIds = new ArrayList();
                modelIds.add(project.getArtifactId());
            }

            // Load the metadata file from an xml file (presumably generated
            // by an earlier execution of the build-metadata goal.
            Model model = IOUtils.loadModel(new File(buildDirectory,
                    metadataFile));

            // Flatten the model so that the template can access every property
            // of each model item directly, even when the property is actually
            // defined on an ancestor class or interface.
            new Flattener(model).flatten();

            generateConfigFromVelocity(model);
        }
        catch (IOException e)
        {
            throw new MojoExecutionException("Error during config generation", e);
        }
        catch (BuildException e)
        {
            throw new MojoExecutionException("Error during config generation", e);
        }
    }
    
    private void generateConfigFromVelocity(Model model) throws IOException,
        MojoExecutionException
    {    
        VelocityEngine velocityEngine = initVelocity();

        VelocityContext baseContext = new VelocityContext();
        baseContext.put("utils", new MyfacesUtils());
        
        String baseContent = "";
        
        if (xmlBaseFile != null && xmlBaseFile.exists())
        {
            getLog().info("using base content file: "+xmlBaseFile.getPath());
            
            Reader reader = null;
            try
            {
                reader = new FileReader(xmlBaseFile);
                Xpp3Dom root = Xpp3DomBuilder.build(reader);
                
                StringWriter writer = new StringWriter();
                
                Xpp3Dom [] children = root.getChildren();
                
                for (int i = 0; i< children.length; i++)
                {
                    Xpp3Dom dom = children[i];
                    Xpp3DomWriter.write(writer, dom);
                    writer.write('\n');
                }
                baseContent = writer.toString();
                writer.close();
            }
            catch (XmlPullParserException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            finally
            {
                reader.close();
            }
        }
        
        baseContext.put("baseContent", baseContent);
        
        baseContext.put("model", model);
        
        baseContext.put("modelIds", modelIds);
        
        if (params != null)
        {
            //Load all parameters to the context, so the template can
            //load it. This allow to generate any config file we want
            //(faces-config, tld, facelet,....)
            for (Iterator it = params.keySet().iterator(); it.hasNext();)
            {
                String key = (String) it.next();
                baseContext.put(key,params.get(key));
            }
        }
        
        Writer writer = null;
        File outFile = null;
        
        try
        {
            outFile = new File(buildDirectory, xmlFile);
            
            if ( !outFile.getParentFile().exists() )
            {
                outFile.getParentFile().mkdirs();
            }
            
            writer = new OutputStreamWriter(new FileOutputStream(outFile));
            
            Template template = velocityEngine.getTemplate(templateFile);
            
            template.merge(baseContext, writer);

            writer.flush();
        }
        catch (ResourceNotFoundException e)
        {
            throw new MojoExecutionException(
                    "Error merging velocity templates: " + e.getMessage(), e);
        }
        catch (ParseErrorException e)
        {
            throw new MojoExecutionException(
                    "Error merging velocity templates: " + e.getMessage(), e);
        }
        catch (Exception e)
        {
            throw new MojoExecutionException(
                    "Error merging velocity templates: " + e.getMessage(), e);
        }
        finally
        {
            IOUtil.close(writer);
            writer = null;
        }        
    }

    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", "xmlMacros.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" );
                        
        VelocityEngine velocityEngine = new VelocityEngine();
                
        try
        {
            velocityEngine.init(p);
        }
        catch (Exception e)
        {
            throw new MojoExecutionException("Error creating VelocityEngine", e);
        }
        
        return velocityEngine;
    }
    
}
