package org.apache.maven.doxia.docrenderer;

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

import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import org.apache.maven.doxia.Doxia;
import org.apache.maven.doxia.document.DocumentModel;
import org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Reader;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.parser.ParseException;
import org.apache.maven.doxia.parser.Parser;
import org.apache.maven.doxia.parser.manager.ParserNotFoundException;
import org.apache.maven.doxia.logging.PlexusLoggerWrapper;
import org.apache.maven.doxia.module.site.SiteModule;
import org.apache.maven.doxia.module.site.manager.SiteModuleManager;

import org.codehaus.plexus.logging.AbstractLogEnabled;

import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 * Abstract <code>document</code> renderer.
 *
 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 * @author ltheussl
 * @version $Id$
 * @since 1.1
 */
public abstract class AbstractDocumentRenderer
    extends AbstractLogEnabled
    implements DocumentRenderer
{
    /** @plexus.requirement */
    protected SiteModuleManager siteModuleManager;

    /** @plexus.requirement */
    protected Doxia doxia;

    /**
     * The common base directory of source files.
     */
    private String baseDir;

      //--------------------------------------------
     //
    //--------------------------------------------

    /**
     * Render an aggregate document from the files found in a Map.
     *
     * @param filesToProcess the Map of Files to process. The Map should contain as keys the paths of the
     *      source files (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
     * @param outputDirectory the output directory where the aggregate document should be generated.
     * @param documentModel the document model, containing all the metadata, etc.
     * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
     * @throws java.io.IOException if any
     */
    public abstract void render( Map filesToProcess, File outputDirectory, DocumentModel documentModel )
        throws DocumentRendererException, IOException;

      //--------------------------------------------
     //
    //--------------------------------------------

    /** {@inheritDoc} */
    public void render( Collection files, File outputDirectory, DocumentModel documentModel )
        throws DocumentRendererException, IOException
    {
        render( getFilesToProcess( files ), outputDirectory, documentModel );
    }

    /** {@inheritDoc} */
    public void render( File baseDirectory, File outputDirectory, DocumentModel documentModel )
        throws DocumentRendererException, IOException
    {
        render( getFilesToProcess( baseDirectory ), outputDirectory, documentModel );
    }

    /**
     * Render a document from the files found in baseDirectory. This just forwards to
     *              {@link #render(File,File,DocumentModel)} with a new DocumentModel.
     *
     * @param baseDirectory the directory containing the source files.
     *              This should follow the standard Maven convention, ie containing all the site modules.
     * @param outputDirectory the output directory where the document should be generated.
     * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
     * @throws java.io.IOException if any
     * @see #render(File, File, DocumentModel)
     */
    public void render( File baseDirectory, File outputDirectory )
        throws DocumentRendererException, IOException
    {
        render( baseDirectory, outputDirectory, (DocumentModel) null );
    }

    /**
     * Render a document from the files found in baseDirectory.
     *
     * @param baseDirectory the directory containing the source files.
     *              This should follow the standard Maven convention, ie containing all the site modules.
     * @param outputDirectory the output directory where the document should be generated.
     * @param documentDescriptor a file containing the document model.
     *              If this file does not exist or is null, some default settings will be used.
     * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
     * @throws java.io.IOException if any
     * @see #render(File, File) if documentDescriptor does not exist or is null
     * @see #render(Map, File, DocumentModel) otherwise
     */
    public void render( File baseDirectory, File outputDirectory, File documentDescriptor )
        throws DocumentRendererException, IOException
    {
        if ( ( documentDescriptor == null ) || ( !documentDescriptor.exists() ) )
        {
            if ( getLogger().isWarnEnabled() )
            {
                getLogger().warn( "No documentDescriptor found: using default settings!" );
            }

            render( baseDirectory, outputDirectory );
        }
        else
        {
            render( getFilesToProcess( baseDirectory ), outputDirectory, readDocumentModel( documentDescriptor ) );
        }
    }

    /**
     * Render documents separately for each file found in a Map.
     *
     * @param filesToProcess the Map of Files to process. The Map should contain as keys the paths of the
     *      source files (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
     * @param outputDirectory the output directory where the documents should be generated.
     * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
     * @throws java.io.IOException if any
     * @since 1.1.1
     */
    public void renderIndividual( Map filesToProcess, File outputDirectory )
        throws DocumentRendererException, IOException
    {
        // nop
    }

    /**
     * Returns a Map of files to process. The Map contains as keys the paths of the source files
     *      (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
     *
     * @param baseDirectory the directory containing the source files.
     *              This should follow the standard Maven convention, ie containing all the site modules.
     * @return a Map of files to process.
     * @throws java.io.IOException in case of a problem reading the files under baseDirectory.
     * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException if any
     */
    public Map getFilesToProcess( File baseDirectory )
        throws IOException, DocumentRendererException
    {
        if ( !baseDirectory.isDirectory() )
        {
            if ( getLogger().isWarnEnabled() )
            {
                getLogger().warn( "No files found to process!" );
            }

            return new HashMap();
        }

        setBaseDir( baseDirectory.getAbsolutePath() );

        Map filesToProcess = new LinkedHashMap();
        Map duplicatesFiles = new LinkedHashMap();

        for ( Iterator i = siteModuleManager.getSiteModules().iterator(); i.hasNext(); )
        {
            SiteModule module = (SiteModule) i.next();

            File moduleBasedir = new File( baseDirectory, module.getSourceDirectory() );

            if ( moduleBasedir.exists() )
            {
                // TODO: handle in/excludes
                List allFiles = FileUtils.getFileNames( moduleBasedir, "**/*.*", null, false );

                String lowerCaseExtension = module.getExtension().toLowerCase( Locale.ENGLISH );
                List docs = new LinkedList( allFiles );
                // Take care of extension case
                for ( Iterator it = docs.iterator(); it.hasNext(); )
                {
                    String name = it.next().toString().trim();

                    if ( !name.toLowerCase( Locale.ENGLISH ).endsWith( "." + lowerCaseExtension ) )
                    {
                        it.remove();
                    }
                }

                for ( Iterator j = docs.iterator(); j.hasNext(); )
                {
                    String filePath = j.next().toString().trim();

                    if ( filePath.lastIndexOf( "." ) > 0 )
                    {
                        String key = filePath.substring( 0, filePath.lastIndexOf( "." ) );

                        if ( duplicatesFiles.containsKey( key ) )
                        {
                            throw new DocumentRendererException( "Files '" + module.getSourceDirectory()
                                + File.separator + filePath + "' clashes with existing '"
                                + duplicatesFiles.get( key ) + "'." );
                        }

                        duplicatesFiles.put( key, module.getSourceDirectory() + File.separator + filePath );
                    }

                    filesToProcess.put( filePath, module );
                }
            }
        }

        return filesToProcess;
    }

    /**
     * Returns a Map of files to process. The Map contains as keys the paths of the source files
     *      (relative to {@link #getBaseDir() baseDir}), and the corresponding SiteModule as values.
     *
     * @param files The Collection of source files.
     * @return a Map of files to process.
     */
    public Map getFilesToProcess( Collection files )
    {
        // ----------------------------------------------------------------------
        // Map all the file names to parser ids
        // ----------------------------------------------------------------------

        Map filesToProcess = new HashMap();

        for ( Iterator it = siteModuleManager.getSiteModules().iterator(); it.hasNext(); )
        {
            SiteModule siteModule = (SiteModule) it.next();

            String extension = "." + siteModule.getExtension();

            String sourceDirectory = File.separator + siteModule.getSourceDirectory() + File.separator;

            for ( Iterator j = files.iterator(); j.hasNext(); )
            {
                String file = (String) j.next();

                // first check if the file path contains one of the recognized source dir identifiers
                // (there's trouble if a pathname contains 2 identifiers), then match file extensions (not unique).

                if ( file.indexOf( sourceDirectory ) != -1 )
                {
                    filesToProcess.put( file, siteModule );
                }
                else if ( file.toLowerCase( Locale.ENGLISH ).endsWith( extension ) )
                {
                    // don't overwrite if it's there already
                    if ( !filesToProcess.containsKey( file ) )
                    {
                        filesToProcess.put( file, siteModule );
                    }
                }
            }
        }

        return filesToProcess;
    }

    /** {@inheritDoc} */
    public DocumentModel readDocumentModel( File documentDescriptor )
        throws DocumentRendererException, IOException
    {
        DocumentModel documentModel;

        Reader reader = null;
        try
        {
            reader = ReaderFactory.newXmlReader( documentDescriptor );
            documentModel = new DocumentXpp3Reader().read( reader );
        }
        catch ( XmlPullParserException e )
        {
            throw new DocumentRendererException( "Error parsing document descriptor", e );
        }
        finally
        {
            IOUtil.close( reader );
        }

        return documentModel;
    }

    /**
     * Sets the current base directory.
     *
     * @param newDir the absolute path to the base directory to set.
     */
    public void setBaseDir( String newDir )
    {
        this.baseDir = newDir;
    }

    /**
     * Return the current base directory.
     *
     * @return the current base directory.
     */
    public String getBaseDir()
    {
        return this.baseDir;
    }

      //--------------------------------------------
     //
    //--------------------------------------------

    /**
     * Parse a source document into a sink.
     *
     * @param fullDocPath absolute path to the source document.
     * @param parserId determines the parser to use.
     * @param sink the sink to receive the events.
     * @throws org.apache.maven.doxia.docrenderer.DocumentRendererException in case of a parsing error.
     * @throws java.io.IOException if the source document cannot be opened.
     */
    protected void parse( String fullDocPath, String parserId, Sink sink )
        throws DocumentRendererException, IOException
    {
        if ( getLogger().isDebugEnabled() )
        {
            getLogger().debug( "Parsing file " + fullDocPath );
        }

        Reader reader = null;
        try
        {
            File f = new File( fullDocPath );

            Parser parser = doxia.getParser( parserId );
            switch ( parser.getType() )
            {
                case Parser.XML_TYPE:
                    reader = ReaderFactory.newXmlReader( f );
                    break;

                case Parser.TXT_TYPE:
                case Parser.UNKNOWN_TYPE:
                default:
                    // TODO Platform dependent?
                    reader = ReaderFactory.newPlatformReader( f );
            }

            sink.enableLogging( new PlexusLoggerWrapper( getLogger() ) );

            doxia.parse( reader, parserId, sink );
        }
        catch ( ParserNotFoundException e )
        {
            throw new DocumentRendererException( "No parser '" + parserId
                        + "' found for " + fullDocPath + ": " + e.getMessage() );
        }
        catch ( ParseException e )
        {
            throw new DocumentRendererException( "Error parsing " + fullDocPath + ": " + e.getMessage(), e );
        }
        finally
        {
            IOUtil.close( reader );

            sink.flush();
        }
    }

    /**
     * Copies the contents of the resource directory to an output folder.
     *
     * @param outputDirectory the destination folder.
     * @throws java.io.IOException if any.
     */
    protected void copyResources( File outputDirectory )
            throws IOException
    {
        File resourcesDirectory = new File( getBaseDir(), "resources" );

        if ( !resourcesDirectory.isDirectory() )
        {
            return;
        }

        if ( !outputDirectory.exists() )
        {
            outputDirectory.mkdirs();
        }

        copyDirectory( resourcesDirectory, outputDirectory );
    }

    /**
     * Copy content of a directory, excluding scm-specific files.
     *
     * @param source directory that contains the files and sub-directories to be copied.
     * @param destination destination folder.
     * @throws java.io.IOException if any.
     */
    protected void copyDirectory( File source, File destination )
            throws IOException
    {
        if ( source.isDirectory() && destination.isDirectory() )
        {
            DirectoryScanner scanner = new DirectoryScanner();

            String[] includedResources = {"**/**"};

            scanner.setIncludes( includedResources );

            scanner.addDefaultExcludes();

            scanner.setBasedir( source );

            scanner.scan();

            List includedFiles = Arrays.asList( scanner.getIncludedFiles() );

            for ( Iterator j = includedFiles.iterator(); j.hasNext(); )
            {
                String name = (String) j.next();

                File sourceFile = new File( source, name );

                File destinationFile = new File( destination, name );

                FileUtils.copyFile( sourceFile, destinationFile );
            }
        }
    }

    /**
     * @param documentModel not null
     * @return the output name defined in the documentModel without the output extension. If the output name is not
     * defined, return target by default.
     * @since 1.1.1
     * @see org.apache.maven.doxia.document.DocumentModel#getOutputName()
     * @see #getOutputExtension()
     */
    protected String getOutputName( DocumentModel documentModel )
    {
        String outputName = documentModel.getOutputName();
        if ( outputName == null )
        {
            getLogger().info( "No outputName is defined in the document descriptor. Using 'target'" );

            documentModel.setOutputName( "target" );
        }

        outputName = outputName.trim();
        if ( outputName.toLowerCase( Locale.ENGLISH ).endsWith( "." + getOutputExtension() ) )
        {
            outputName =
                outputName.substring( 0, outputName.toLowerCase( Locale.ENGLISH )
                                                   .lastIndexOf( "." + getOutputExtension() ) );
        }
        documentModel.setOutputName( outputName );

        return documentModel.getOutputName();
    }
}
