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

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.apache.myfaces.buildtools.maven2.plugin.builder.Flattener;
import org.apache.myfaces.buildtools.maven2.plugin.builder.IOUtils;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.BehaviorMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ClassMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ComponentMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ConverterMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.FaceletFunctionMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.FaceletTagMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.Model;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.TagMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.model.ValidatorMeta;
import org.apache.myfaces.buildtools.maven2.plugin.builder.utils.MyfacesUtils;
import org.apache.velocity.runtime.resource.ResourceManagerImpl;

/**
 * Report for generating JSF tagdoc index based on myfaces-metadata.xml parsing.
 * The content is generated using velocity in xdoc files (see TagdocContentMojo).
 *
 * @author Leonardo Uribe
 * @goal tagdoc-index
 */
public class TagdocIndexReport extends AbstractMavenReport
{
    private Model _model;

    /**
     * Specifies the directory where the report will be generated
     *
     * @parameter default-value="${project.reporting.outputDirectory}"
     * @required
     */
    private File outputDirectory;

    /**
     * Directory where the original site is present.
     * (TRIED using ${baseDir}/src/site;  that inserted a 'null' into
     * the string for some reason.  TRIED using ${siteDirectory},
     * which was undefined.  TRIED ${project.directory}src/site; which also
     * inserted a null.  ${project.build.directory}/../src/site seems to work,
     * though it assumes that ${project.build.directory} is 
     * ${project.directory}/target.
     * 
     * @parameter default-value="${project.build.directory}/../src/site/"
     * @required
     */
    private File siteDirectory;

    /**
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    private MavenProject project;

    /**
     * @component
     */
    private Renderer siteRenderer;

    /**
     * @parameter
     */
    private Map taglibs;

    /**
     * @parameter expression="${project.build.directory}/generated-resources/myfaces-builder-plugin"
     */
    private File buildDirectory;

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

    /**
     * @parameter
     */
    private List modelIds;

    /**
     * component role="org.codehaus.plexus.velocity.VelocityComponent" roleHint="tagdoc"
     */
    //private VelocityComponent velocityComponent;
    static private final String _DOC_SUBDIRECTORY = "tagdoc";

    protected void executeReport(Locale locale) throws MavenReportException
    {

        if (modelIds == null)
        {
            modelIds = new ArrayList();
            modelIds.add(project.getArtifactId());
        }

        if (taglibs == null)
        {
            taglibs = new HashMap();
            taglibs.put("t", "http://myfaces.apache.org/tomahawk");
        }

        try
        {
            _model = IOUtils.loadModel(new File(buildDirectory, metadataFile));
            new Flattener(_model).flatten();
            _generateTagDocs();
        }
        catch (Exception e)
        {
            throw new MavenReportException("Couldn't generate tagdoc", e);
        }
    }

    public boolean canGenerate(ClassMeta component)
    {
        if (modelIds.contains(component.getModelId()))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    public boolean canGenerate(FaceletFunctionMeta component)
    {
        if (modelIds.contains(component.getModelId()))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    public class CustomResourceManagerImpl extends ResourceManagerImpl
    {

        public CustomResourceManagerImpl()
        {
            super();
        }

    }

    private void _generateTagDocs() throws Exception
    {
        Model model = getModel();
        if (model.getComponents().size() == 0)
        {
            getLog().info("Nothing to generate - no components found");
            return;
        }

        Iterator components = model.components();

        Iterator validators = model.validators();

        Iterator converters = model.converters();
        
        Iterator behaviors = model.behaviors();
        
        Iterator tags = model.tags();
        
        Iterator faceletTags = model.faceletTags();
        
        Iterator faceletFunctions = model.faceletFunctions();
        
        Map<String, List<FaceletFunctionMeta>> faceletFunctionByModelId = 
            new HashMap<String, List<FaceletFunctionMeta>>();
        
        // =-=AEW Note that only updating out-of-date components, etc. is
        // permanently tricky, even if we had proper detection in place,
        // because the index always has to have all docs
        /*
        if (!components.hasNext() && !converters.hasNext() && !validators.hasNext())
        {
          getLog().info("Nothing to generate - all docs are up to date");
          return;
        }
        */

        Set componentPages = new TreeSet();
        Set converterPages = new TreeSet();
        Set behaviorPages = new TreeSet();
        Set validatorPages = new TreeSet();
        Set tagsPages = new TreeSet();
        Set faceletTagPages = new TreeSet();
        Set faceletFunctionPages = new TreeSet();

        int count = 0;
        while (components.hasNext())
        {
            ComponentMeta component = (ComponentMeta) components.next();
            if (canGenerate(component))
            {
                String pageName = _generateComponentDoc(component);
                if (pageName != null)
                {
                    componentPages.add(pageName);
                    count++;
                }
            }
        }
        while (converters.hasNext())
        {
            ConverterMeta converter = (ConverterMeta) converters.next();
            if (canGenerate(converter))
            {
                String pageName = _generateConverterDoc(converter);
                if (pageName != null)
                {
                    converterPages.add(pageName);
                    count++;
                }
            }
        }
        while (validators.hasNext())
        {
            ValidatorMeta validator = (ValidatorMeta) validators.next();

            if (canGenerate(validator))
            {
                String pageName = _generateValidatorDoc(validator);
                if (pageName != null)
                {
                    validatorPages.add(pageName);
                    count++;
                }
            }
        }
        while (behaviors.hasNext())
        {
            BehaviorMeta behavior = (BehaviorMeta) behaviors.next();
            if (canGenerate(behavior))
            {
                String pageName = _generateBehaviorDoc(behavior);
                if (pageName != null)
                {
                    behaviorPages.add(pageName);
                    count++;
                }
            }
        }

        while (tags.hasNext())
        {
            TagMeta tag = (TagMeta) tags.next();
            
            if (canGenerate(tag))
            {
                String pageName = _generateTagDoc(tag);
                if (pageName != null)
                {
                    tagsPages.add(pageName);
                    count++;
                }                
            }
        }
        
        while (faceletTags.hasNext())
        {
            FaceletTagMeta faceletTag = (FaceletTagMeta) faceletTags.next();
            
            if (canGenerate(faceletTag))
            {
                String pageName = _generateFaceletTagDoc(model, faceletTag);
                if (pageName != null)
                {
                    faceletTagPages.add(pageName);
                    count++;
                }
            }
        }
        
        for (int i = 0; i < modelIds.size(); i++)
        {
            String modelId = (String) modelIds.get(i);
            
            faceletFunctionByModelId.put(modelId, new ArrayList<FaceletFunctionMeta>());
        }

        while (faceletFunctions.hasNext())
        {
            FaceletFunctionMeta faceletFunction = (FaceletFunctionMeta) faceletFunctions.next();
            
            if (canGenerate(faceletFunction))
            {
                String pageName = _generateFaceletFunctionDoc(model, faceletFunction);
                if (pageName != null)
                {
                    faceletFunctionPages.add(pageName);
                    count++;
                }
            }
        }
        
        Set otherPages = _gatherOtherTags();

        getLog().info("Generated " + count + " page(s)");

        Sink sink = getSink();
        sink.head();
        sink.title();
        sink.text("Tag library documentation");
        sink.title_();
        sink.head_();
        sink.body();

        sink.sectionTitle1();
        sink.text("Tag library information");
        sink.sectionTitle1_();
        sink.section1();

        for (Iterator i = taglibs.entrySet().iterator(); i.hasNext();)
        {
            Map.Entry entry = (Map.Entry) i.next();
            sink.paragraph();

            sink.bold();
            sink.text("Short name:");
            sink.bold_();
            sink.nonBreakingSpace();
            sink.text(entry.getKey().toString());
            sink.lineBreak();

            sink.bold();
            sink.text("Namespace:");
            sink.bold_();
            sink.nonBreakingSpace();
            sink.text(entry.getValue().toString());
            sink.lineBreak();

            sink.paragraph_();
        }

        sink.section1_();

        _writeIndexSection(sink, componentPages, "Components");
        _writeIndexSection(sink, converterPages, "Converters");
        _writeIndexSection(sink, validatorPages, "Validators");
        _writeIndexSection(sink, behaviorPages, "Behaviors");
        _writeIndexSection(sink, tagsPages, "JSF Tags");
        _writeIndexSection(sink, faceletTagPages, "JSF Facelet Tags");
        _writeIndexSection(sink, faceletFunctionPages, "JSF Facelet EL Functions", "Function Name");
        _writeIndexSection(sink, otherPages, "Miscellaneous");

        sink.body_();
    }

    private Set _gatherOtherTags()
    {
        TreeSet set = new TreeSet();
        String subDir = _platformAgnosticPath(_platformAgnosticPath("xdoc/"
                + _DOC_SUBDIRECTORY));
        File siteSubDir = new File(siteDirectory, subDir);
        if (siteSubDir.exists())
        {
            String[] files = siteSubDir.list();
            for (int i = 0; i < files.length; i++)
            {
                String file = files[i];
                if (file.endsWith(".xml"))
                {
                    set.add(file.substring(0, file.length() - 4));
                }
            }
        }

        return set;
    }

    private void _writeIndexSection(Sink sink, Set pages, String title)
    {
        _writeIndexSection(sink, pages, title, "Tag Name");
    }
    
    private void _writeIndexSection(Sink sink, Set pages, String title, String typeName)
    {
        if (pages.isEmpty())
        {
            return;
        }

        sink.sectionTitle1();
        sink.text(title);
        sink.sectionTitle1_();
        sink.section1();
        sink.table();
        sink.tableRow();
        sink.tableHeaderCell();
        sink.text(typeName);
        sink.tableHeaderCell_();
        sink.tableRow_();

        Iterator iter = pages.iterator();
        while (iter.hasNext())
        {
            sink.tableRow();
            sink.tableCell();

            String name = (String) iter.next();
            String tagName = "<" + name.replace('_', ':') + ">";

            sink.link(_DOC_SUBDIRECTORY + "/" + name + ".html");
            sink.text(tagName);
            sink.link_();

            sink.tableCell_();
            sink.tableRow_();
        }

        sink.table_();
        sink.section1_();
    }
    
    public boolean usePageLinkBar()
    {
        return false;
    }

    private String _toPageName(String qName)
    {
        return MyfacesUtils.getTagPrefix(qName) + "_"
                + MyfacesUtils.getTagName(qName);
    }

    private String _generateComponentDoc(ComponentMeta component)
            throws Exception
    {
        if (component.getName() == null)
        {
            return null;
        }
        String pageName = _toPageName(component.getName());

        return pageName;
    }

    private String _generateConverterDoc(ConverterMeta converter)
            throws IOException
    {
        if (converter.getName() == null)
        {
            return null;
        }

        String pageName = _toPageName(converter.getName());

        return pageName;
    }
    
    private String _generateBehaviorDoc(BehaviorMeta behavior)
            throws IOException
    {
        if (behavior.getName() == null)
        {
            return null;
        }
        
        String pageName = _toPageName(behavior.getName());
        
        return pageName;
    }

    private String _generateValidatorDoc(ValidatorMeta validator)
            throws IOException
    {
        if (validator.getName() == null)
        {
            return null;
        }

        String pageName = _toPageName(validator.getName());

        return pageName;
    }
    
    private String _generateTagDoc(TagMeta tag)
        throws IOException
    {
        if (tag.getName() == null)
        {
            return null;
        }
        
        String pageName = _toPageName(tag.getName());
        
        return pageName;
    }
    
    private String _generateFaceletFunctionDoc(Model model, FaceletFunctionMeta faceletFunction)
    throws IOException
    {
        if (faceletFunction.getName() == null)
        {
            return null;
        }
        
        String pageName = _toPageName(faceletFunction.getName());
        
        return pageName;
    }
    
    private String _generateFaceletTagDoc(Model model, FaceletTagMeta tag)
    throws IOException
    {
        String name = tag.getName(); 
        if (name == null)
        {
            return null;
        }
        
        if (tag.getComponentClass() != null)
        {
            ComponentMeta comp = model.findComponentByClassName(tag.getComponentClass());
            if (name.equals(comp.getName()))
            {
                //Exists in jsp and in facelets, but has specific facelets properties
                return null;
            }
        }
        if (tag.getConverterClass() != null)
        {
            ConverterMeta comp = model.findConverterByClassName(tag.getConverterClass());
            if (name.equals(comp.getName()))
            {
                //Exists in jsp and in facelets, but has specific facelets properties
                return null;
            }            
        }
        if (tag.getValidatorClass() != null)
        {
            ValidatorMeta comp = model.findValidatorByClassName(tag.getValidatorClass());
            if (name.equals(comp.getName()))
            {
                //Exists in jsp and in facelets, but has specific facelets properties
                return null;
            }            
        }
        if (tag.getBehaviorClass() != null)
        {
            BehaviorMeta comp = model.findBehaviorByClassName(tag.getBehaviorClass());
            if (name.equals(comp.getName()))
            {
                //Exists in jsp and in facelets, but has specific facelets properties
                return null;
            }            
        }

        if (tag.getTagClass() != null)
        {
            TagMeta comp = model.findTagByClassName(tag.getTagClass());
            if (name.equals(comp.getName()))
            {
                //Exists in jsp and in facelets, but has specific facelets properties
                return null;
            }
        }
        
        String pageName = _toPageName(tag.getName());
        
        return pageName;
    }   

    static private final String _platformAgnosticPath(String path)
    {
        return path.replace('/', File.separatorChar);
    }

    protected MavenProject getProject()
    {
        return project;
    }

    protected String getOutputDirectory()
    {
        return outputDirectory.getAbsolutePath();
    }

    protected Renderer getSiteRenderer()
    {
        return siteRenderer;
    }

    public String getName(Locale locale)
    {
        return "JSF Tag Documentation";
    }

    public String getDescription(Locale locale)
    {
        return "Documentation for JSF Tags";
    }

    public String getOutputName()
    {
        return "tagdoc";
    }

    protected Model getModel()
    {
        return _model;
    }

}