/*
 *  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.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.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;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.siterenderer.Renderer;

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

        // =-=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();

        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++;
                }
            }
        }
        

        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, 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)
    {
        if (pages.isEmpty())
        {
            return;
        }

        sink.sectionTitle1();
        sink.text(title);
        sink.sectionTitle1_();
        sink.section1();
        sink.table();
        sink.tableRow();
        sink.tableHeaderCell();
        sink.text("Tag Name");
        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 _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;
    }

}