/*
 *  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.plugins.jsdoc;

import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.xml.stream.XMLStreamException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.commons.lang.StringUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.project.MavenProject;
import org.apache.maven.reporting.MavenReportException;
import org.apache.myfaces.plugins.jsdoc.util.HTMLFileContentFilter;
import org.apache.myfaces.plugins.jsdoc.util.JSDocPackMaven;
import org.apache.myfaces.plugins.jsdoc.util.JSFileNameFilter;
import org.apache.myfaces.plugins.jsdoc.util.XMLConfig;

public abstract class AbstractJSDocMojo extends AbstractMojo
{
    
    // ----------------------------------------------------------------------
    // Mojo components
    // ----------------------------------------------------------------------

    // ----------------------------------------------------------------------
    // Mojo parameters
    // ----------------------------------------------------------------------
    
    /**
     * The Maven Project Object
     *
     * @parameter expression="${project}"
     * @required
     * @readonly
     */
    protected MavenProject project;
    
    /**
     * the root project build dir (target directory)
     *
     * @parameter expression="${project.build.directory}"
     */
    protected String projectBuildDir;
    
    // ----------------------------------------------------------------------
    // Standard Options
    // ----------------------------------------------------------------------
    
    /**
     * The project source javascript directory, which are the source 
     * files unprocessed by myfaces javascript plugin
     *
     * @parameter expression="${basedir}/src/main/javascript/"
     */
    protected String sourceDirectory;
    
    /**
     * The relative dir name sourceDirectory is
     *
     * @parameter expression="src/main/javascript/"
     */
    protected String relativeSourceDirectory;
    
    /**
     * The project resource directory, to take all files ending 
     * with .js 
     *
     * @parameter expression="${basedir}/src/main/resources/"
     */
    protected File resourceDirectory;
    
    /**
     * The relative dir name resourceDirectory is
     *
     * @parameter expression="src/main/resources/"
     */
    protected String relativeResourceDirectory;
    
    
    /**
     * The project webapp directory, to take all files ending
     * with .js
     *
     * @parameter expression="${basedir}/src/main/webapp/"
     */
    protected String webappDirectory;
    
    /**
     * The relative dir name webappDirectory is
     *
     * @parameter expression="src/main/webapp/"
     */
    protected String relativeWebappDirectory;
    
    /**
     * Specifies the destination directory where jsdoc saves the generated HTML files.
     *
     * @parameter expression="${destDir}" alias="destDir" default-value="${project.build.directory}/jsdoc"
     * @required
     */
    protected File outputDirectory;
    
    /**
     * Path to the assembly file containing the file paths to our source javascript files
     *
     * @parameter expression="${basedir}/src/assembler/jsdoc-compiler.xml"
     */
    protected String assemblyFile;
    
    /**
     * Specifies whether the Javadoc generation should be skipped.
     *
     * @since 2.5
     * @parameter expression="${myfaces.jsdoc.skip}" default-value="false"
     */
    protected boolean skip;
    
    // ----------------------------------------------------------------------
    // Standard JSDoc Options
    // ----------------------------------------------------------------------
    
    //various jsdoc params, copied over as well as the corresponding snippets from
    /**
     * Whether to include symbols tagged as private. Default is <code>false</code>.
     *
     * @parameter expression="false"
     */
    protected boolean includePrivate;

    /**
     * Include all functions, even undocumented ones. Default is <code>false</code>.
     *
     * @parameter expression="false"
     */
    protected boolean includeUndocumented;

    /**
     * Include all functions, even undocumented, underscored ones. Default is <code>false</code>.
     *
     * @parameter expression="false"
     */
    protected boolean includeUndocumentedUnderscored;

    /**
     * template directory used by jsdoc the default is <code>templates/jsdoc</code> under the jsdoc root
     *
     * @parameter expression="templates/jsdoc"
     */
    protected String templates;

    // ----------------------------------------------------------------------
    // protected methods
    // ----------------------------------------------------------------------

    protected void executeReport( Locale unusedLocale )
        throws MavenReportException
    {
        JSDocHelper helper = _setup();
        try
        {
            _execute(helper);
        }
        catch (IOException e)
        {
            throw new MavenReportException(e.toString());
        }
        finally
        {
            _tearDown(helper);
        }  
    }

    /**
     * @return the output directory
     */
    protected String getOutputDirectory()
    {
        return outputDirectory.getAbsoluteFile().toString();
    }
    
    protected MavenProject getProject()
    {
        return project;
    }
    
    // ----------------------------------------------------------------------
    // private methods
    // ----------------------------------------------------------------------
    
    protected JSDocHelper _setup() throws MavenReportException
    {
        JSDocHelper helper = new JSDocHelper();
        try
        {
            if (new File(assemblyFile).exists())
            {
                helper.setFileMap(new XMLConfig(assemblyFile));
            }
        }
        catch (XMLStreamException e)
        {
            getLog().error(e);
            throw new MavenReportException(e.toString());
        }
        catch (FileNotFoundException e)
        {
            getLog().error(e);
            throw new MavenReportException(e.toString());
        }
        helper.setUnpacker(new JSDocPackMaven());
        //unpacker = new JSDocPackResources();

        helper.setJsdocRunPath(projectBuildDir + File.separator + JSDocMojoConst.JSDOC);
        helper.setJsdocEngineUnpacked(projectBuildDir + File.separator + JSDocMojoConst.TEMP
                + File.separator + JSDocMojoConst.JSDOC);

        helper.setJavascriptTargetPath(helper.getJsdocRunPath() + File.separator + JSDocMojoConst.JAVASCRIPT);

        File pathCreator = new File(helper.getJsdocEngineUnpacked());
        File jsdocPathCreator = new File(helper.getJavascriptTargetPath());
        pathCreator.mkdirs();
        jsdocPathCreator.mkdirs();
        return helper;
    }

    public void _tearDown(JSDocHelper helper) throws MavenReportException
    {
        try
        {
            FileUtils.deleteDirectory(new File(helper.getJsdocEngineUnpacked()));
        }
        catch (IOException e)
        {
            throw new MavenReportException(e.toString());
        }
    }

    protected void _execute(JSDocHelper helper) throws MavenReportException, IOException
    {

        copyJavascripts(helper);

        //fetchJavascriptSources(helper);
        //now we have all files we now can now work on our plugin call
        unpackJSDoc(helper);

        String systemJsdocDir = setenvJSDocDir(helper);
        String userDir = setenvUserDir(helper);
        try
        {
            executeJSDoc(helper);
        }
        finally
        {
            resetSysenvVars(systemJsdocDir, userDir);
        }
    }

    private void resetSysenvVars(String systemJsdocDir, String userDir)
    {
        if (systemJsdocDir != null)
        {
            System.setProperty(JSDocMojoConst.JSDOC_DIR, systemJsdocDir);
        }
        if (userDir != null)
        {
            System.setProperty("user.dir", userDir);
        }
    }

    private void executeJSDoc(JSDocHelper helper)
    {
        List args = _initArguments(helper);

        getLog().info("[JSDOC] Executing within maven: '" + args.toString().replaceAll(",", "") + "'");

        // tell Rhino to run JSDoc with the provided params
        // without calling System.exit

        org.mozilla.javascript.tools.shell.Main.main((String[]) args.toArray(new String[0]));

        this.fixHTML(helper);
    }

    private String setenvUserDir(JSDocHelper helper)
    {
        String userDir = System.getProperty("user.dir");
        System.setProperty("user.dir", helper.getJsdocEngineUnpacked() + File.separator);
        return userDir;
    }

    private String setenvJSDocDir(JSDocHelper helper)
    {
        String systemJsdocDir = System.getProperty(JSDocMojoConst.JSDOC_DIR);
        System.setProperty(JSDocMojoConst.JSDOC_DIR, helper.getJsdocEngineUnpacked() + File.separator);
        return systemJsdocDir;
    }

    private void unpackJSDoc(JSDocHelper helper) throws IOException
    {
        getLog().info("[JSDOC] Unpacking jsdoc toolkit for further processing");
        helper.getUnpacker().unpack(helper.getJsdocEngineUnpacked(), getLog());
        getLog().info("[JSDOC] Unpacking jsdoc toolkit for further processing done");
    }

    /**
     * initially copies all source files from the given source dir to the target
     * dir so that the files can be referenced later on by the html files
     */
    private void copyJavascripts(JSDocHelper helper) throws IOException
    {
        getLog().info("[JSDOC] Copying all javascript sources to the target dir for later reference");
        
        if (!StringUtils.isEmpty(sourceDirectory))
        {
            File buildSourceDirFile = new File(sourceDirectory);
            if (buildSourceDirFile.exists())
            {
                FileUtils.copyDirectory(
                        buildSourceDirFile, 
                        new File(helper.getJavascriptTargetPath()+'/'+relativeSourceDirectory), 
                        new FileFilter()
                {
                    
                    public boolean accept(File pathname)
                    {
                        if (pathname.getName().endsWith(".svn"))
                        {
                            return false;
                        }
                        return true;
                    }
                });
            }
        }

        if (resourceDirectory != null)
        {
            if (resourceDirectory.exists())
            {
                FileUtils.copyDirectory(
                        resourceDirectory, 
                        new File(helper.getJavascriptTargetPath()+'/'+relativeResourceDirectory), 
                        new FileFilter()
                {
                    
                    public boolean accept(File pathname)
                    {
                        if (pathname.getName().endsWith(".svn"))
                        {
                            return false;
                        }
                        if (pathname.isDirectory())
                        {
                            return true;
                        }
                        if (pathname.getName().endsWith(".js"))
                        {
                            return true;
                        }
                        return false;
                    }
                });
            }
        }
        
        if (!StringUtils.isEmpty(webappDirectory))
        {
            File buildWebappSourceDirFile = new File(webappDirectory);
            if (buildWebappSourceDirFile.exists())
            {
                FileUtils.copyDirectory(
                        buildWebappSourceDirFile, 
                        new File(helper.getJavascriptTargetPath()+'/'+relativeWebappDirectory), 
                        new FileFilter()
                {
                    
                    public boolean accept(File pathname)
                    {
                        if (pathname.getName().endsWith(".svn"))
                        {
                            return false;
                        }
                        if (pathname.isDirectory())
                        {
                            return true;
                        }
                        if (pathname.getName().endsWith(".js"))
                        {
                            return true;
                        }
                        return false;
                    }
                });
            }
        }
        
        getLog().info("[JSDOC] Copying done without any errors");
    }

    private final List _initArguments(JSDocHelper helper)
    {
        List args = new ArrayList();
        String runJsPath = helper.getJsdocEngineUnpacked() + File.separator + JSDocMojoConst.APP
                + File.separator + JSDocMojoConst.RUN_JS;
        args.add(runJsPath);

        if (this.includeUndocumented)
        {
            args.add(JSDocMojoConst.PARAM_UNDOCUMENTED);
        }
        if (this.includeUndocumentedUnderscored)
        {
            args.add(JSDocMojoConst.PARAM_UNDOCUMENTED_UNDERSCORED);
        }
        if (this.includePrivate)
        {
            args.add(JSDocMojoConst.PARAM_PRIVATE);
        }
        args.add(JSDocMojoConst.PARAM_OUTPUT + JSDocMojoConst.EQUALS + this.getOutputDirectory());
        args.add(JSDocMojoConst.PARAM_TEMPLATE + JSDocMojoConst.EQUALS + getTemplateDirectory(helper));

        args.addAll(fetchJavascriptSources(helper));
        //according to the run.js source the last argument
        //must be a -j param pointing to the jsdoc javascripts
        args.add(JSDocMojoConst.PARAM_JS_FLAG + JSDocMojoConst.EQUALS + runJsPath);
        return args;
    }

    /**
     * @return the directory as absolute path holding the jsdoc toolkit templates
     */
    private final String getTemplateDirectory(JSDocHelper helper)
    {
        return (JSDocMojoConst.TEMPLATES_JSDOC.equals(this.templates)) ?
                helper.getJsdocEngineUnpacked() + File.separator + this.templates :
                this.templates;
    }

    /**
     * @return the target directory for the jsdoc files
     */
    /*
    private final String getOutputDirectory()
    {
        return (this.outputDirectory == null || this.outputDirectory.equals("")) ?
                projectBuildDir + File.separator + JSDocMojoConst.JSDOC :
                this.outputDirectory;

    }*/

    /**
     * @return fetches the sources for the javascripts in the order given by the xml
     */
    private List<String> fetchJavascriptSources(JSDocHelper helper)
    {
        List<String> sources = null;
        getLog().info("[JSDOC] Fetch Javascript sources for further processing");
        if (helper.getFileMap() == null)
        {
            sources = new ArrayList<String>();
            File javascriptTargetFileBase = new File(helper.getJavascriptTargetPath());
            addSources(sources, javascriptTargetFileBase);
            return sources;
        }
        else
        {
            JSFileNameFilter fileNameFilter = new JSFileNameFilter(helper.getFileMap());
            //FileUtils.iterateFiles(new File(getOutputDirectory()), fileNameFilter, TrueFileFilter.INSTANCE);
            FileUtils.iterateFiles(new File(helper.getJavascriptTargetPath()), fileNameFilter, TrueFileFilter.INSTANCE);
    
            Map sortedResult = fileNameFilter.getSortedResults();
            sources = new ArrayList(sortedResult.size());
            Iterator it = sortedResult.entrySet().iterator();
            while (it.hasNext())
            {
                Map.Entry singleItem = (Map.Entry) it.next();
                String finalFileName = (String) singleItem.getValue();
                sources.add(finalFileName);
            }
        }
        getLog().info("[JSDOC] All Javascript sources are prepared for processing");
        return sources;
    }
    
    private void addSources(List<String> sources, File file)
    {
        if (file.isDirectory())
        {
            File[] files = file.listFiles();
            if (files != null)
            {
                for (int i = 0; i < files.length; i++)
                {
                    addSources(sources, files[i]);
                }
            }
        }
        else
        {
            sources.add(file.getAbsolutePath());
        }
    }

    private void fixHTML(JSDocHelper helper)
    {
        FileUtils.iterateFiles(new File(getOutputDirectory()), 
                new HTMLFileContentFilter(helper.getJavascriptTargetPath()),
                TrueFileFilter.INSTANCE);
    }

}
