/*
 *  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 java.util.logging.Logger;

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.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.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.codehaus.doxia.sink.Sink;
import org.codehaus.doxia.site.renderer.SiteRenderer;

/**
 * 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
{
    final Logger log = Logger.getLogger(TagdocIndexReport.class.getName());

    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
     * @required
     * @readonly
     */
    private SiteRenderer siteRenderer;

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

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

    /**
     * @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 tags = model.tags();

        // =-=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 validatorPages = new TreeSet();
        Set tagsPages = 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 (tags.hasNext())
        {
            TagMeta tag = (TagMeta) tags.next();
            
            if (canGenerate(tag))
            {
                String pageName = _generateTagDoc(tag);
                if (pageName != null)
                {
                    tagsPages.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, tagsPages, "JSF 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 _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;
    }    

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

    protected MavenProject getProject()
    {
        return project;
    }

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

    protected SiteRenderer 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;
    }

}