package org.apache.maven.doxia.siterenderer;

/*
 * 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.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.LineNumberReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
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 java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.Restriction;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.doxia.Doxia;
import org.apache.maven.doxia.logging.PlexusLoggerWrapper;
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.site.decoration.DecorationModel;
import org.apache.maven.doxia.site.decoration.PublishDate;
import org.apache.maven.doxia.site.skin.SkinModel;
import org.apache.maven.doxia.site.skin.io.xpp3.SkinXpp3Reader;
import org.apache.maven.doxia.parser.module.ParserModule;
import org.apache.maven.doxia.parser.module.ParserModuleManager;
import org.apache.maven.doxia.parser.module.ParserModuleNotFoundException;
import org.apache.maven.doxia.siterenderer.sink.SiteRendererSink;
import org.apache.maven.doxia.util.XmlValidator;
import org.apache.velocity.Template;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.VelocityException;
import org.apache.velocity.tools.Scope;
import org.apache.velocity.tools.ToolManager;
import org.apache.velocity.tools.config.ConfigurationUtils;
import org.apache.velocity.tools.config.EasyFactoryConfiguration;
import org.apache.velocity.tools.config.FactoryConfiguration;
import org.apache.velocity.tools.generic.AlternatorTool;
import org.apache.velocity.tools.generic.ClassTool;
import org.apache.velocity.tools.generic.ComparisonDateTool;
import org.apache.velocity.tools.generic.ContextTool;
import org.apache.velocity.tools.generic.ConversionTool;
import org.apache.velocity.tools.generic.DisplayTool;
import org.apache.velocity.tools.generic.EscapeTool;
import org.apache.velocity.tools.generic.FieldTool;
import org.apache.velocity.tools.generic.LinkTool;
import org.apache.velocity.tools.generic.LoopTool;
import org.apache.velocity.tools.generic.MathTool;
import org.apache.velocity.tools.generic.NumberTool;
import org.apache.velocity.tools.generic.RenderTool;
import org.apache.velocity.tools.generic.ResourceTool;
import org.apache.velocity.tools.generic.SortTool;
import org.apache.velocity.tools.generic.XmlTool;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.i18n.I18N;
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.Os;
import org.codehaus.plexus.util.PathTool;
import org.codehaus.plexus.util.PropertyUtils;
import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.WriterFactory;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.codehaus.plexus.velocity.VelocityComponent;

/**
 * <p>DefaultSiteRenderer class.</p>
 *
 * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
 * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
 * @version $Id$
 * @since 1.0
 */
@Component( role = Renderer.class )
public class DefaultSiteRenderer
    extends AbstractLogEnabled
    implements Renderer
{
    // ----------------------------------------------------------------------
    // Requirements
    // ----------------------------------------------------------------------

    @Requirement
    private VelocityComponent velocity;

    @Requirement
    private ParserModuleManager parserModuleManager;

    @Requirement
    private Doxia doxia;

    @Requirement
    private I18N i18n;

    @Requirement
    private PlexusContainer plexus;

    private static final String RESOURCE_DIR = "org/apache/maven/doxia/siterenderer/resources";

    private static final String DEFAULT_TEMPLATE = RESOURCE_DIR + "/default-site.vm";

    private static final String SKIN_TEMPLATE_LOCATION = "META-INF/maven/site.vm";

    private static final String TOOLS_LOCATION = "META-INF/maven/site-tools.xml";

    // ----------------------------------------------------------------------
    // Renderer implementation
    // ----------------------------------------------------------------------

    /** {@inheritDoc} */
    public Map<String, DocumentRenderer> locateDocumentFiles( SiteRenderingContext siteRenderingContext )
            throws IOException, RendererException
    {
        Map<String, DocumentRenderer> files = new LinkedHashMap<String, DocumentRenderer>();
        Map<String, String> moduleExcludes = siteRenderingContext.getModuleExcludes();

        // look in every site directory (in general src/site or target/generated-site)
        for ( File siteDirectory : siteRenderingContext.getSiteDirectories() )
        {
            if ( siteDirectory.exists() )
            {
                Collection<ParserModule> modules = parserModuleManager.getParserModules();
                // use every Doxia parser module
                for ( ParserModule module : modules )
                {
                    File moduleBasedir = new File( siteDirectory, module.getSourceDirectory() );

                    String excludes = ( moduleExcludes == null ) ? null : moduleExcludes.get( module.getParserId() );

                    addModuleFiles( moduleBasedir, module, excludes, files );
                }
            }
        }

        // look in specific modules directories (used for old Maven 1.x site layout: xdoc and fml docs in /xdocs)
        for ( ExtraDoxiaModuleReference module : siteRenderingContext.getModules() )
        {
            try
            {
                ParserModule parserModule = parserModuleManager.getParserModule( module.getParserId() );

                String excludes = ( moduleExcludes == null ) ? null : moduleExcludes.get( module.getParserId() );

                addModuleFiles( module.getBasedir(), parserModule, excludes, files );
            }
            catch ( ParserModuleNotFoundException e )
            {
                throw new RendererException( "Unable to find module: " + e.getMessage(), e );
            }
        }
        return files;
    }

    private List<String> filterExtensionIgnoreCase( List<String> fileNames, String extension )
    {
        List<String> filtered = new LinkedList<String>( fileNames );
        for ( Iterator<String> it = filtered.iterator(); it.hasNext(); )
        {
            String name = it.next();

            // Take care of extension case
            if ( !endsWithIgnoreCase( name, extension ) )
            {
                it.remove();
            }
        }
        return filtered;
    }

    private void addModuleFiles( File moduleBasedir, ParserModule module, String excludes,
                                 Map<String, DocumentRenderer> files )
            throws IOException, RendererException
    {
        if ( !moduleBasedir.exists() || ArrayUtils.isEmpty( module.getExtensions() ) )
        {
            return;
        }

        List<String> allFiles = FileUtils.getFileNames( moduleBasedir, "**/*.*", excludes, false );

        for ( String extension : module.getExtensions() )
        {
            String fullExtension = "." + extension;

            List<String> docs = filterExtensionIgnoreCase( allFiles, fullExtension );

            // *.<extension>.vm
            List<String> velocityFiles = filterExtensionIgnoreCase( allFiles, fullExtension + ".vm" );

            docs.addAll( velocityFiles );

            for ( String doc : docs )
            {
                RenderingContext context =
                        new RenderingContext( moduleBasedir, doc, module.getParserId(), extension );

                // TODO: DOXIA-111: we need a general filter here that knows how to alter the context
                if ( endsWithIgnoreCase( doc, ".vm" ) )
                {
                    context.setAttribute( "velocity", "true" );
                }

                String key = context.getOutputName();
                key = StringUtils.replace( key, "\\", "/" );

                if ( files.containsKey( key ) )
                {
                    DocumentRenderer renderer = files.get( key );

                    RenderingContext originalContext = renderer.getRenderingContext();

                    File originalDoc = new File( originalContext.getBasedir(), originalContext.getInputName() );

                    throw new RendererException( "File '" + module.getSourceDirectory() + File.separator + doc
                        + "' clashes with existing '" + originalDoc + "'." );
                }
                // -----------------------------------------------------------------------
                // Handle key without case differences
                // -----------------------------------------------------------------------
                for ( Map.Entry<String, DocumentRenderer> entry : files.entrySet() )
                {
                    if ( entry.getKey().equalsIgnoreCase( key ) )
                    {
                        RenderingContext originalContext = entry.getValue().getRenderingContext();

                        File originalDoc = new File( originalContext.getBasedir(), originalContext.getInputName() );

                        if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
                        {
                            throw new RendererException( "File '" + module.getSourceDirectory() + File.separator
                                + doc + "' clashes with existing '" + originalDoc + "'." );
                        }

                        if ( getLogger().isWarnEnabled() )
                        {
                            getLogger().warn( "File '" + module.getSourceDirectory() + File.separator + doc
                                + "' could clash with existing '" + originalDoc + "'." );
                        }
                    }
                }

                files.put( key, new DoxiaDocumentRenderer( context ) );
            }
        }
    }

    /** {@inheritDoc} */
    public void render( Collection<DocumentRenderer> documents, SiteRenderingContext siteRenderingContext,
                        File outputDirectory )
        throws RendererException, IOException
    {
        for ( DocumentRenderer docRenderer : documents )
        {
            RenderingContext renderingContext = docRenderer.getRenderingContext();

            File outputFile = new File( outputDirectory, docRenderer.getOutputName() );

            File inputFile = new File( renderingContext.getBasedir(), renderingContext.getInputName() );

            boolean modified = !outputFile.exists() || ( inputFile.lastModified() > outputFile.lastModified() )
                || ( siteRenderingContext.getDecoration().getLastModified() > outputFile.lastModified() );

            if ( modified || docRenderer.isOverwrite() )
            {
                if ( !outputFile.getParentFile().exists() )
                {
                    outputFile.getParentFile().mkdirs();
                }

                if ( getLogger().isDebugEnabled() )
                {
                    getLogger().debug( "Generating " + outputFile );
                }

                Writer writer = null;
                try
                {
                    if ( !docRenderer.isExternalReport() )
                    {
                        writer = WriterFactory.newWriter( outputFile, siteRenderingContext.getOutputEncoding() );
                    }
                    docRenderer.renderDocument( writer, this, siteRenderingContext );
                }
                finally
                {
                    IOUtil.close( writer );
                }
            }
            else
            {
                if ( getLogger().isDebugEnabled() )
                {
                    getLogger().debug( inputFile + " unchanged, not regenerating..." );
                }
            }
        }
    }

    /** {@inheritDoc} */
    public void renderDocument( Writer writer, RenderingContext renderingContext, SiteRenderingContext siteContext )
            throws RendererException, FileNotFoundException, UnsupportedEncodingException
    {
        SiteRendererSink sink = new SiteRendererSink( renderingContext );

        File doc = new File( renderingContext.getBasedir(), renderingContext.getInputName() );

        Reader reader = null;
        try
        {
            String resource = doc.getAbsolutePath();

            Parser parser = doxia.getParser( renderingContext.getParserId() );
            // DOXIASITETOOLS-146 don't render comments from source markup
            parser.setEmitComments( false );

            // TODO: DOXIA-111: the filter used here must be checked generally.
            if ( renderingContext.getAttribute( "velocity" ) != null )
            {
                getLogger().debug( "Processing Velocity for " + renderingContext.getInputName() );
                try
                {
                    Context vc = createDocumentVelocityContext( renderingContext, siteContext );

                    StringWriter sw = new StringWriter();

                    velocity.getEngine().mergeTemplate( resource, siteContext.getInputEncoding(), vc, sw );

                    String doxiaContent = sw.toString();

                    if ( siteContext.getProcessedContentOutput() != null )
                    {
                        // save Velocity processing result, ie the Doxia content that will be parsed after
                        if ( !siteContext.getProcessedContentOutput().exists() )
                        {
                            siteContext.getProcessedContentOutput().mkdirs();
                        }

                        String input = renderingContext.getInputName();
                        File outputFile = new File( siteContext.getProcessedContentOutput(),
                                                    input.substring( 0, input.length() - 3 ) );

                        File outputParent = outputFile.getParentFile();
                        if ( !outputParent.exists() )
                        {
                            outputParent.mkdirs();
                        }

                        FileUtils.fileWrite( outputFile, siteContext.getInputEncoding(), doxiaContent );
                    }

                    reader = new StringReader( doxiaContent );
                }
                catch ( Exception e )
                {
                    if ( getLogger().isDebugEnabled() )
                    {
                        getLogger().error( "Error parsing " + resource + " as a velocity template, using as text.", e );
                    }
                    else
                    {
                        getLogger().error( "Error parsing " + resource + " as a velocity template, using as text." );
                    }
                }

                if ( parser.getType() == Parser.XML_TYPE && siteContext.isValidate() )
                {
                    reader = validate( reader, resource );
                }
            }
            else
            {
                switch ( parser.getType() )
                {
                    case Parser.XML_TYPE:
                        reader = ReaderFactory.newXmlReader( doc );
                        if ( siteContext.isValidate() )
                        {
                            reader = validate( reader, resource );
                        }
                        break;

                    case Parser.TXT_TYPE:
                    case Parser.UNKNOWN_TYPE:
                    default:
                        reader = ReaderFactory.newReader( doc, siteContext.getInputEncoding() );
                }
            }
            sink.enableLogging( new PlexusLoggerWrapper( getLogger() ) );

            if ( reader == null ) // can happen if velocity throws above
            {
                throw new RendererException( "Error getting a parser for '" + doc + "'" );
            }
            doxia.parse( reader, renderingContext.getParserId(), sink );
        }
        catch ( ParserNotFoundException e )
        {
            throw new RendererException( "Error getting a parser for '" + doc + "': " + e.getMessage(), e );
        }
        catch ( ParseException e )
        {
            throw new RendererException( "Error parsing '"
                    + doc + "': line [" + e.getLineNumber() + "] " + e.getMessage(), e );
        }
        catch ( IOException e )
        {
            throw new RendererException( "IOException when processing '" + doc + "'", e );
        }
        finally
        {
            sink.flush();

            sink.close();

            IOUtil.close( reader );
        }

        generateDocument( writer, sink, siteContext );
    }

    /**
     * Creates a Velocity Context with all generic tools configured wit the site rendering context.
     *
     * @param siteRenderingContext the site rendering context
     * @return a Velocity tools managed context
     */
    protected Context createToolManagedVelocityContext( SiteRenderingContext siteRenderingContext )
    {
        Locale locale = siteRenderingContext.getLocale();
        String dateFormat = siteRenderingContext.getDecoration().getPublishDate().getFormat();

        EasyFactoryConfiguration config = new EasyFactoryConfiguration( false );
        config.property( "safeMode", Boolean.FALSE );
        config.toolbox( Scope.REQUEST )
            .tool( ContextTool.class )
            .tool( LinkTool.class )
            .tool( LoopTool.class )
            .tool( RenderTool.class );
        config.toolbox( Scope.APPLICATION ).property( "locale", locale )
            .tool( AlternatorTool.class )
            .tool( ClassTool.class )
            .tool( ComparisonDateTool.class ).property( "format", dateFormat )
            .tool( ConversionTool.class ).property( "dateFormat", dateFormat )
            .tool( DisplayTool.class )
            .tool( EscapeTool.class )
            .tool( FieldTool.class )
            .tool( MathTool.class )
            .tool( NumberTool.class )
            .tool( ResourceTool.class ).property( "bundles", new String[] { "site-renderer" } )
            .tool( SortTool.class )
            .tool( XmlTool.class );

        FactoryConfiguration customConfig = ConfigurationUtils.findInClasspath( TOOLS_LOCATION );

        if ( customConfig != null )
        {
            config.addConfiguration( customConfig );
        }

        ToolManager manager = new ToolManager( false, false );
        manager.configure( config );

        return manager.createContext();
    }

    /**
     * Create a Velocity Context for a Doxia document, containing every information about rendered document.
     *
     * @param sink the site renderer sink for the document
     * @param siteRenderingContext the site rendering context
     * @return
     */
    protected Context createDocumentVelocityContext( RenderingContext renderingContext,
                                                     SiteRenderingContext siteRenderingContext )
    {
        Context context = createToolManagedVelocityContext( siteRenderingContext );
        // ----------------------------------------------------------------------
        // Data objects
        // ----------------------------------------------------------------------

        context.put( "relativePath", renderingContext.getRelativePath() );

        String currentFileName = renderingContext.getOutputName().replace( '\\', '/' );
        context.put( "currentFileName", currentFileName );

        context.put( "alignedFileName", PathTool.calculateLink( currentFileName, renderingContext.getRelativePath() ) );

        context.put( "decoration", siteRenderingContext.getDecoration() );

        Locale locale = siteRenderingContext.getLocale();
        context.put( "locale", locale );
        context.put( "supportedLocales", Collections.unmodifiableList( siteRenderingContext.getSiteLocales() ) );

        context.put( "currentDate", new Date() );
        SimpleDateFormat sdf = new SimpleDateFormat( "yyyyMMdd" );
        context.put( "dateRevision", sdf.format( new Date() ) );

        context.put( "publishDate", siteRenderingContext.getPublishDate() );

        PublishDate publishDate = siteRenderingContext.getDecoration().getPublishDate();
        DateFormat dateFormat = new SimpleDateFormat( publishDate.getFormat(), locale );
        context.put( "dateFormat", dateFormat );

        // doxiaSiteRendererVersion
        InputStream inputStream = this.getClass().getResourceAsStream( "/META-INF/"
            + "maven/org.apache.maven.doxia/doxia-site-renderer/pom.properties" );
        Properties properties = PropertyUtils.loadProperties( inputStream );
        if ( inputStream == null )
        {
            getLogger().debug( "pom.properties for doxia-site-renderer could not be found." );
        }
        else if ( properties == null )
        {
            getLogger().debug( "Failed to load pom.properties, so doxiaVersion is not available"
                + " in the Velocity context." );
        }
        else
        {
            context.put( "doxiaSiteRendererVersion", properties.getProperty( "version" ) );
        }

        // Add user properties
        Map<String, ?> templateProperties = siteRenderingContext.getTemplateProperties();

        if ( templateProperties != null )
        {
            for ( Map.Entry<String, ?> entry : templateProperties.entrySet() )
            {
                context.put( entry.getKey(), entry.getValue() );
            }
        }

        // ----------------------------------------------------------------------
        // Tools
        // ----------------------------------------------------------------------

        context.put( "PathTool", new PathTool() );

        context.put( "FileUtils", new FileUtils() );

        context.put( "StringUtils", new StringUtils() );

        context.put( "i18n", i18n );

        context.put( "plexus", plexus );
        return context;
    }

    /**
     * Create a Velocity Context for the site template decorating the document. In addition to all the informations
     * from the document, this context contains data gathered in {@link SiteRendererSink} during document rendering.
     *
     * @param siteRendererSink the site renderer sink for the document
     * @param siteRenderingContext the site rendering context
     * @return
     */
    protected Context createSiteTemplateVelocityContext( SiteRendererSink siteRendererSink,
                                                         SiteRenderingContext siteRenderingContext )
    {
        // first get the context from document
        Context context = createDocumentVelocityContext( siteRendererSink.getRenderingContext(), siteRenderingContext );

        // then add data objects from rendered document

        // Add infos from document
        context.put( "authors", siteRendererSink.getAuthors() );

        context.put( "shortTitle", siteRendererSink.getTitle() );

        // DOXIASITETOOLS-70: Prepend the project name to the title, if any
        String title = "";
        if ( siteRenderingContext.getDecoration() != null
                && siteRenderingContext.getDecoration().getName() != null )
        {
            title = siteRenderingContext.getDecoration().getName();
        }
        else if ( siteRenderingContext.getDefaultWindowTitle() != null )
        {
            title = siteRenderingContext.getDefaultWindowTitle();
        }

        if ( title.length() > 0 )
        {
            title += " &#x2013; "; // Symbol Name: En Dash, Html Entity: &ndash;
        }
        title += siteRendererSink.getTitle();

        context.put( "title", title );

        context.put( "headContent", siteRendererSink.getHead() );

        context.put( "bodyContent", siteRendererSink.getBody() );

        // document date (got from Doxia Sink date() API)
        String documentDate = siteRendererSink.getDate();
        if ( StringUtils.isNotEmpty( documentDate ) )
        {
            context.put( "documentDate", documentDate );

            // deprecated variables that rework the document date, suppose one semantics over others
            // (ie creation date, while it may be last modification date if the document writer decided so)
            // see DOXIASITETOOLS-20 for the beginning and DOXIASITETOOLS-164 for the end of this story
            try
            {
                // we support only ISO 8601 date
                Date creationDate = new SimpleDateFormat( "yyyy-MM-dd" ).parse( documentDate );

                context.put( "creationDate", creationDate );
                SimpleDateFormat sdf = new SimpleDateFormat( "yyyyMMdd" );
                context.put( "dateCreation", sdf.format( creationDate ) );
            }
            catch ( java.text.ParseException e )
            {
                getLogger().warn( "Could not parse date '" + documentDate + "' from "
                    + siteRendererSink.getRenderingContext().getInputName()
                    + " (expected yyyy-MM-dd format), ignoring!" );
            }
        }

        return context;
    }

    /** {@inheritDoc} */
    public void generateDocument( Writer writer, SiteRendererSink sink, SiteRenderingContext siteRenderingContext )
            throws RendererException
    {
        String templateName = siteRenderingContext.getTemplateName();

        getLogger().debug( "Processing Velocity for template " + templateName + " on "
            + sink.getRenderingContext().getInputName() );

        Context context = createSiteTemplateVelocityContext( sink, siteRenderingContext );

        ClassLoader old = null;

        if ( siteRenderingContext.getTemplateClassLoader() != null )
        {
            // -------------------------------------------------------------------------
            // If no template classloader was set we'll just use the context classloader
            // -------------------------------------------------------------------------

            old = Thread.currentThread().getContextClassLoader();

            Thread.currentThread().setContextClassLoader( siteRenderingContext.getTemplateClassLoader() );
        }

        try
        {
            Template template;
            Artifact skin = siteRenderingContext.getSkin();

            try
            {
                SkinModel skinModel = siteRenderingContext.getSkinModel();
                String encoding = ( skinModel == null ) ? null : skinModel.getEncoding();

                template = ( encoding == null ) ? velocity.getEngine().getTemplate( templateName )
                                : velocity.getEngine().getTemplate( templateName, encoding );
            }
            catch ( ParseErrorException pee )
            {
                throw new RendererException( "Velocity parsing error while reading the site decoration template "
                    + ( ( skin == null ) ? ( "'" + templateName + "'" ) : ( "from " + skin.getId() + " skin" ) ),
                                             pee );
            }
            catch ( ResourceNotFoundException rnfe )
            {
                throw new RendererException( "Could not find the site decoration template "
                    + ( ( skin == null ) ? ( "'" + templateName + "'" ) : ( "from " + skin.getId() + " skin" ) ),
                                             rnfe );
            }

            try
            {
                StringWriter sw = new StringWriter();
                template.merge( context, sw );
                writer.write( sw.toString().replaceAll( "\r?\n", SystemUtils.LINE_SEPARATOR ) );
            }
            catch ( VelocityException ve )
            {
                throw new RendererException( "Velocity error while merging site decoration template.", ve );
            }
            catch ( IOException ioe )
            {
                throw new RendererException( "IO exception while merging site decoration template.", ioe );
            }
        }
        finally
        {
            IOUtil.close( writer );

            if ( old != null )
            {
                Thread.currentThread().setContextClassLoader( old );
            }
        }
    }

    private SiteRenderingContext createSiteRenderingContext( Map<String, ?> attributes, DecorationModel decoration,
                                                             String defaultWindowTitle, Locale locale )
    {
        SiteRenderingContext context = new SiteRenderingContext();

        context.setTemplateProperties( attributes );
        context.setLocale( locale );
        context.setDecoration( decoration );
        context.setDefaultWindowTitle( defaultWindowTitle );

        return context;
    }

    /** {@inheritDoc} */
    public SiteRenderingContext createContextForSkin( Artifact skin, Map<String, ?> attributes,
                                                      DecorationModel decoration, String defaultWindowTitle,
                                                      Locale locale )
            throws IOException, RendererException
    {
        SiteRenderingContext context = createSiteRenderingContext( attributes, decoration, defaultWindowTitle, locale );

        context.setSkin( skin );

        ZipFile zipFile = getZipFile( skin.getFile() );
        InputStream in = null;

        try
        {
            if ( zipFile.getEntry( SKIN_TEMPLATE_LOCATION ) != null )
            {
                context.setTemplateName( SKIN_TEMPLATE_LOCATION );
                context.setTemplateClassLoader( new URLClassLoader( new URL[]{skin.getFile().toURI().toURL()} ) );
            }
            else
            {
                context.setTemplateName( DEFAULT_TEMPLATE );
                context.setTemplateClassLoader( getClass().getClassLoader() );
                context.setUsingDefaultTemplate( true );
            }

            ZipEntry skinDescriptorEntry = zipFile.getEntry( SkinModel.SKIN_DESCRIPTOR_LOCATION );
            if ( skinDescriptorEntry != null )
            {
                in = zipFile.getInputStream( skinDescriptorEntry );

                SkinModel skinModel = new SkinXpp3Reader().read( in );
                context.setSkinModel( skinModel );

                String toolsPrerequisite =
                    skinModel.getPrerequisites() == null ? null : skinModel.getPrerequisites().getDoxiaSitetools();

                Package p = DefaultSiteRenderer.class.getPackage();
                String current = ( p == null ) ? null : p.getSpecificationVersion();

                if ( StringUtils.isNotBlank( toolsPrerequisite ) && ( current != null )
                    && !matchVersion( current, toolsPrerequisite ) )
                {
                    throw new RendererException( "Cannot use skin: has " + toolsPrerequisite
                        + " Doxia Sitetools prerequisite, but current is " + current );
                }
            }
        }
        catch ( XmlPullParserException e )
        {
            throw new RendererException( "Failed to parse " + SkinModel.SKIN_DESCRIPTOR_LOCATION
                + " skin descriptor from " + skin.getId() + " skin", e );
        }
        finally
        {
            IOUtil.close( in );
            closeZipFile( zipFile );
        }

        return context;
    }

    boolean matchVersion( String current, String prerequisite )
        throws RendererException
    {
        try
        {
            ArtifactVersion v = new DefaultArtifactVersion( current );
            VersionRange vr = VersionRange.createFromVersionSpec( prerequisite );

            boolean matched = false;
            ArtifactVersion recommendedVersion = vr.getRecommendedVersion();
            if ( recommendedVersion == null )
            {
                List<Restriction> restrictions = vr.getRestrictions();
                for ( Restriction restriction : restrictions )
                {
                    if ( restriction.containsVersion( v ) )
                    {
                        matched = true;
                        break;
                    }
                }
            }
            else
            {
                // only singular versions ever have a recommendedVersion
                @SuppressWarnings( "unchecked" )
                int compareTo = recommendedVersion.compareTo( v );
                matched = ( compareTo <= 0 );
            }

            if ( getLogger().isDebugEnabled() )
            {
                getLogger().debug( "Skin doxia-sitetools prerequisite: " + prerequisite + ", current: " + current
                    + ", matched = " + matched );
            }

            return matched;
        }
        catch ( InvalidVersionSpecificationException e )
        {
            throw new RendererException( "Invalid skin doxia-sitetools prerequisite: " + prerequisite, e );
        }
    }

    /** {@inheritDoc} */
    @Deprecated
    public SiteRenderingContext createContextForTemplate( File templateFile, Map<String, ?> attributes,
                                                          DecorationModel decoration, String defaultWindowTitle,
                                                          Locale locale )
            throws MalformedURLException
    {
        SiteRenderingContext context = createSiteRenderingContext( attributes, decoration, defaultWindowTitle, locale );

        context.setTemplateName( templateFile.getName() );
        context.setTemplateClassLoader( new URLClassLoader( new URL[]{templateFile.getParentFile().toURI().toURL()} ) );

        return context;
    }

    /** {@inheritDoc} */
    public void copyResources( SiteRenderingContext siteRenderingContext, File resourcesDirectory,
                               File outputDirectory )
        throws IOException
    {
        throw new AssertionError( "copyResources( SiteRenderingContext, File, File ) is deprecated." );
    }

    /** {@inheritDoc} */
    public void copyResources( SiteRenderingContext siteRenderingContext, File outputDirectory )
        throws IOException
    {
        if ( siteRenderingContext.getSkin() != null )
        {
            ZipFile file = getZipFile( siteRenderingContext.getSkin().getFile() );

            try
            {
                for ( Enumeration<? extends ZipEntry> e = file.entries(); e.hasMoreElements(); )
                {
                    ZipEntry entry = e.nextElement();

                    if ( !entry.getName().startsWith( "META-INF/" ) )
                    {
                        File destFile = new File( outputDirectory, entry.getName() );
                        if ( !entry.isDirectory() )
                        {
                            if ( destFile.exists() )
                            {
                                // don't override existing content: avoids extra rewrite with same content or extra site
                                // resource
                                continue;
                            }

                            destFile.getParentFile().mkdirs();

                            copyFileFromZip( file, entry, destFile );
                        }
                        else
                        {
                            destFile.mkdirs();
                        }
                    }
                }
            }
            finally
            {
                closeZipFile( file );
            }
        }

        if ( siteRenderingContext.isUsingDefaultTemplate() )
        {
            InputStream resourceList = getClass().getClassLoader()
                    .getResourceAsStream( RESOURCE_DIR + "/resources.txt" );

            if ( resourceList != null )
            {
                Reader r = null;
                LineNumberReader reader = null;
                try
                {
                    r = ReaderFactory.newReader( resourceList, ReaderFactory.UTF_8 );
                    reader = new LineNumberReader( r );

                    String line;

                    while ( ( line = reader.readLine() ) != null )
                    {
                        if ( line.startsWith( "#" ) || line.trim().length() == 0 )
                        {
                            continue;
                        }

                        InputStream is = getClass().getClassLoader().getResourceAsStream( RESOURCE_DIR + "/" + line );

                        if ( is == null )
                        {
                            throw new IOException( "The resource " + line + " doesn't exist." );
                        }

                        File outputFile = new File( outputDirectory, line );

                        if ( outputFile.exists() )
                        {
                            // don't override existing content: avoids extra rewrite with same content or extra site
                            // resource
                            continue;
                        }

                        if ( !outputFile.getParentFile().exists() )
                        {
                            outputFile.getParentFile().mkdirs();
                        }

                        OutputStream os = null;
                        try
                        {
                            // for the images
                            os = new FileOutputStream( outputFile );
                            IOUtil.copy( is, os );
                        }
                        finally
                        {
                            IOUtil.close( os );
                        }

                        IOUtil.close( is );
                    }
                }
                finally
                {
                    IOUtil.close( reader );
                    IOUtil.close( r );
                }
            }
        }

        // Copy extra site resources
        for ( File siteDirectory : siteRenderingContext.getSiteDirectories() )
        {
            File resourcesDirectory = new File( siteDirectory, "resources" );

            if ( resourcesDirectory != null && resourcesDirectory.exists() )
            {
                copyDirectory( resourcesDirectory, outputDirectory );
            }
        }

        // Check for the existence of /css/site.css
        File siteCssFile = new File( outputDirectory, "/css/site.css" );
        if ( !siteCssFile.exists() )
        {
            // Create the subdirectory css if it doesn't exist, DOXIA-151
            File cssDirectory = new File( outputDirectory, "/css/" );
            boolean created = cssDirectory.mkdirs();
            if ( created && getLogger().isDebugEnabled() )
            {
                getLogger().debug(
                    "The directory '" + cssDirectory.getAbsolutePath() + "' did not exist. It was created." );
            }

            // If the file is not there - create an empty file, DOXIA-86
            if ( getLogger().isDebugEnabled() )
            {
                getLogger().debug(
                    "The file '" + siteCssFile.getAbsolutePath() + "' does not exist. Creating an empty file." );
            }
            Writer writer = null;
            try
            {
                writer = WriterFactory.newWriter( siteCssFile, siteRenderingContext.getOutputEncoding() );
                //DOXIA-290...the file should not be 0 bytes.
                writer.write( "/* You can override this file with your own styles */"  );
            }
            finally
            {
                IOUtil.close( writer );
            }
        }
    }

    private static void copyFileFromZip( ZipFile file, ZipEntry entry, File destFile )
            throws IOException
    {
        FileOutputStream fos = new FileOutputStream( destFile );

        try
        {
            IOUtil.copy( file.getInputStream( entry ), fos );
        }
        finally
        {
            IOUtil.close( fos );
        }
    }

    /**
     * Copy the directory
     *
     * @param source      source file to be copied
     * @param destination destination file
     * @throws java.io.IOException if any
     */
    protected void copyDirectory( File source, File destination )
            throws IOException
    {
        if ( source.exists() )
        {
            DirectoryScanner scanner = new DirectoryScanner();

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

            scanner.setIncludes( includedResources );

            scanner.addDefaultExcludes();

            scanner.setBasedir( source );

            scanner.scan();

            List<String> includedFiles = Arrays.asList( scanner.getIncludedFiles() );

            for ( String name : includedFiles )
            {
                File sourceFile = new File( source, name );

                File destinationFile = new File( destination, name );

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

    private Reader validate( Reader source, String resource )
            throws ParseException, IOException
    {
        getLogger().debug( "Validating: " + resource );

        try
        {
            String content = IOUtil.toString( new BufferedReader( source ) );

            new XmlValidator( new PlexusLoggerWrapper( getLogger() ) ).validate( content );

            return new StringReader( content );
        }
        finally
        {
            IOUtil.close( source );
        }
    }

    // TODO replace with StringUtils.endsWithIgnoreCase() from maven-shared-utils 0.7
    static boolean endsWithIgnoreCase( String str, String searchStr )
    {
        if ( str.length() < searchStr.length() )
        {
            return false;
        }

        return str.regionMatches( true, str.length() - searchStr.length(), searchStr, 0, searchStr.length() );
    }

    private static ZipFile getZipFile( File file )
        throws IOException
    {
        if ( file == null )
        {
            throw new IOException( "Error opening ZipFile: null" );
        }

        try
        {
            // TODO: plexus-archiver, if it could do the excludes
            return new ZipFile( file );
        }
        catch ( ZipException ex )
        {
            IOException ioe = new IOException( "Error opening ZipFile: " + file.getAbsolutePath() );
            ioe.initCause( ex );
            throw ioe;
        }
    }

    private static void closeZipFile( ZipFile zipFile )
    {
        // TODO: move to plexus utils
        try
        {
            zipFile.close();
        }
        catch ( IOException e )
        {
            // ignore
        }
    }
}
