package org.apache.maven.plugins.war.packaging;

/*
 * 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 org.apache.maven.model.Resource;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.war.Overlay;
import org.apache.maven.plugins.war.util.PathSet;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.StringUtils;

/**
 * Handles the project own resources, that is: <ul <li>The list of web resources, if any</li> <li>The content of the
 * webapp directory if it exists</li> <li>The custom deployment descriptor(s), if any</li> <li>The content of the
 * classes directory if it exists</li> <li>The dependencies of the project</li> </ul>
 *
 * @author Stephane Nicoll
 * @version $Id$
 */
public class WarProjectPackagingTask
    extends AbstractWarPackagingTask
{
    private final Resource[] webResources;

    private final File webXml;

    private final File containerConfigXML;

    private final String id;

    private Overlay currentProjectOverlay;

    /**
     * @param webResources {@link #webResources}
     * @param webXml {@link #webXml}
     * @param containerConfigXml {@link #containerConfigXML}
     * @param currentProjectOverlay {@link #currentProjectOverlay}
     */
    public WarProjectPackagingTask( Resource[] webResources, File webXml, File containerConfigXml,
                                    Overlay currentProjectOverlay )
    {
        if ( webResources != null )
        {
            this.webResources = webResources;
        }
        else
        {
            this.webResources = new Resource[0];
        }
        this.webXml = webXml;
        this.containerConfigXML = containerConfigXml;
        this.currentProjectOverlay = currentProjectOverlay;
        this.id = currentProjectOverlay.getId();
    }

    /**
     * {@inheritDoc}
     */
    public void performPackaging( WarPackagingContext context )
        throws MojoExecutionException, MojoFailureException
    {

        context.getLog().info( "Processing war project" );
        // Prepare the INF directories
        File webinfDir = new File( context.getWebappDirectory(), WEB_INF_PATH );
        webinfDir.mkdirs();
        File metainfDir = new File( context.getWebappDirectory(), META_INF_PATH );
        metainfDir.mkdirs();

        handleWebResources( context );

        handeWebAppSourceDirectory( context );

        // Debug mode: dump the path set for the current build
        PathSet pathSet = context.getWebappStructure().getStructure( "currentBuild" );
        context.getLog().debug( "Dump of the current build pathSet content -->" );
        for ( String path : pathSet )
        {
            context.getLog().debug( path );
        }
        context.getLog().debug( "-- end of dump --" );

        handleDeploymentDescriptors( context, webinfDir, metainfDir );

        handleClassesDirectory( context );

        handleArtifacts( context );
    }

    /**
     * Handles the web resources.
     *
     * @param context the packaging context
     * @throws MojoExecutionException if a resource could not be copied
     */
    protected void handleWebResources( WarPackagingContext context )
        throws MojoExecutionException
    {
        for ( Resource resource : webResources )
        {

            // MWAR-246
            if ( resource.getDirectory() == null )
            {
                throw new MojoExecutionException( "The <directory> tag is missing from the <resource> tag." );
            }

            if ( !( new File( resource.getDirectory() ) ).isAbsolute() )
            {
                resource.setDirectory( context.getProject().getBasedir() + File.separator + resource.getDirectory() );
            }

            // Make sure that the resource directory is not the same as the webappDirectory
            if ( !resource.getDirectory().equals( context.getWebappDirectory().getPath() ) )
            {

                try
                {
                    copyResources( context, resource );
                }
                catch ( IOException e )
                {
                    throw new MojoExecutionException( "Could not copy resource [" + resource.getDirectory() + "]", e );
                }
            }
        }
    }

    /**
     * Handles the webapp sources.
     *
     * @param context the packaging context
     * @throws MojoExecutionException if the sources could not be copied
     */
    protected void handeWebAppSourceDirectory( WarPackagingContext context )
        throws MojoExecutionException
    {
        // CHECKSTYLE_OFF: LineLength
        if ( !context.getWebappSourceDirectory().exists() )
        {
            context.getLog().debug( "webapp sources directory does not exist - skipping." );
        }
        else if ( !context.getWebappSourceDirectory().getAbsolutePath().equals( context.getWebappDirectory().getPath() ) )
        {
            context.getLog().info( "Copying webapp resources [" + context.getWebappSourceDirectory() + "]" );
            final PathSet sources =
                getFilesToIncludes( context.getWebappSourceDirectory(), context.getWebappSourceIncludes(),
                                    context.getWebappSourceExcludes(), context.isWebappSourceIncludeEmptyDirectories() );

            try
            {
                copyFiles( id, context, context.getWebappSourceDirectory(), sources, false );
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Could not copy webapp sources ["
                    + context.getWebappDirectory().getAbsolutePath() + "]", e );
            }
        }
        // CHECKSTYLE_ON: LineLength
    }

    /**
     * Handles the webapp artifacts.
     *
     * @param context the packaging context
     * @throws MojoExecutionException if the artifacts could not be packaged
     */
    protected void handleArtifacts( WarPackagingContext context )
        throws MojoExecutionException
    {
        @SuppressWarnings( "unchecked" )
        ArtifactsPackagingTask task =
            new ArtifactsPackagingTask( context.getProject().getArtifacts(), currentProjectOverlay );
        task.performPackaging( context );
    }

    /**
     * Handles the webapp classes.
     *
     * @param context the packaging context
     * @throws MojoExecutionException if the classes could not be packaged
     */
    protected void handleClassesDirectory( WarPackagingContext context )
        throws MojoExecutionException
    {
        ClassesPackagingTask task = new ClassesPackagingTask( currentProjectOverlay );
        task.performPackaging( context );
    }

    /**
     * Handles the deployment descriptors, if specified. Note that the behavior here is slightly different since the
     * customized entry always win, even if an overlay has already packaged a web.xml previously.
     *
     * @param context the packaging context
     * @param webinfDir the web-inf directory
     * @param metainfDir the meta-inf directory
     * @throws MojoFailureException if the web.xml is specified but does not exist
     * @throws MojoExecutionException if an error occurred while copying the descriptors
     */
    protected void handleDeploymentDescriptors( WarPackagingContext context, File webinfDir, File metainfDir )
        throws MojoFailureException, MojoExecutionException
    {
        try
        {
            if ( webXml != null && StringUtils.isNotEmpty( webXml.getName() ) )
            {
                if ( !webXml.exists() )
                {
                    throw new MojoFailureException( "The specified web.xml file '" + webXml + "' does not exist" );
                }

                // Making sure that it won't get overlayed
                context.getWebappStructure().registerFileForced( id, WEB_INF_PATH + "/web.xml" );

                if ( context.isFilteringDeploymentDescriptors() )
                {
                    context.getMavenFileFilter().copyFile( webXml, new File( webinfDir, "web.xml" ), true,
                                                           context.getFilterWrappers(), getEncoding( webXml ) );
                }
                else
                {
                    copyFile( context, webXml, new File( webinfDir, "web.xml" ), "WEB-INF/web.xml", true );
                }
            }
            else
            {
                // the webXml can be the default one
                File defaultWebXml = new File( context.getWebappSourceDirectory(), WEB_INF_PATH + "/web.xml" );
                // if exists we can filter it
                if ( defaultWebXml.exists() && context.isFilteringDeploymentDescriptors() )
                {
                    context.getWebappStructure().registerFile( id, WEB_INF_PATH + "/web.xml" );
                    context.getMavenFileFilter().copyFile( defaultWebXml, new File( webinfDir, "web.xml" ), true,
                                                           context.getFilterWrappers(), getEncoding( defaultWebXml ) );
                }
            }

            if ( containerConfigXML != null && StringUtils.isNotEmpty( containerConfigXML.getName() ) )
            {
                String xmlFileName = containerConfigXML.getName();

                context.getWebappStructure().registerFileForced( id, META_INF_PATH + "/" + xmlFileName );

                if ( context.isFilteringDeploymentDescriptors() )
                {
                    context.getMavenFileFilter().copyFile( containerConfigXML, new File( metainfDir, xmlFileName ),
                                                           true, context.getFilterWrappers(),
                                                           getEncoding( containerConfigXML ) );
                }
                else
                {
                    copyFile( context, containerConfigXML, new File( metainfDir, xmlFileName ), "META-INF/"
                        + xmlFileName, true );
                }
            }
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Failed to copy deployment descriptor", e );
        }
        catch ( MavenFilteringException e )
        {
            throw new MojoExecutionException( "Failed to copy deployment descriptor", e );
        }
    }

    /**
     * Copies webapp webResources from the specified directory.
     *
     * @param context the WAR packaging context to use
     * @param resource the resource to copy
     * @throws IOException if an error occurred while copying the resources
     * @throws MojoExecutionException if an error occurred while retrieving the filter properties
     */
    public void copyResources( WarPackagingContext context, Resource resource )
        throws IOException, MojoExecutionException
    {
        if ( !context.getWebappDirectory().exists() )
        {
            context.getLog().warn( "Not copying webapp webResources [" + resource.getDirectory()
                                       + "]: webapp directory [" + context.getWebappDirectory().getAbsolutePath()
                                       + "] does not exist!" );
        }

        context.getLog().info( "Copying webapp webResources [" + resource.getDirectory() + "] to ["
                                   + context.getWebappDirectory().getAbsolutePath() + "]" );
        String[] fileNames = getFilesToCopy( resource );
        for ( String fileName : fileNames )
        {
            String targetFileName = fileName;
            if ( resource.getTargetPath() != null )
            {
                // TODO make sure this thing is 100% safe
                // MWAR-129 if targetPath is only a dot <targetPath>.</targetPath> or ./
                // and the Resource is in a part of the warSourceDirectory the file from sources will override this
                // that's we don't have to add the targetPath yep not nice but works
                if ( !StringUtils.equals( ".", resource.getTargetPath() )
                    && !StringUtils.equals( "./", resource.getTargetPath() ) )
                {
                    targetFileName = resource.getTargetPath() + File.separator + targetFileName;
                }
            }
            if ( resource.isFiltering() && !context.isNonFilteredExtension( fileName ) )
            {
                copyFilteredFile( id, context, new File( resource.getDirectory(), fileName ), targetFileName );
            }
            else
            {
                copyFile( id, context, new File( resource.getDirectory(), fileName ), targetFileName );
            }
        }
    }

    /**
     * Returns a list of filenames that should be copied over to the destination directory.
     *
     * @param resource the resource to be scanned
     * @return the array of filenames, relative to the sourceDir
     */
    private String[] getFilesToCopy( Resource resource )
    {
        // CHECKSTYLE_OFF: LineLength
        DirectoryScanner scanner = new DirectoryScanner();
        scanner.setBasedir( resource.getDirectory() );
        if ( resource.getIncludes() != null && !resource.getIncludes().isEmpty() )
        {
            scanner.setIncludes( (String[]) resource.getIncludes().toArray( new String[resource.getIncludes().size()] ) );
        }
        else
        {
            scanner.setIncludes( DEFAULT_INCLUDES );
        }
        if ( resource.getExcludes() != null && !resource.getExcludes().isEmpty() )
        {
            scanner.setExcludes( (String[]) resource.getExcludes().toArray( new String[resource.getExcludes().size()] ) );
        }

        scanner.addDefaultExcludes();

        scanner.scan();

        return scanner.getIncludedFiles();
        // CHECKSTYLE_ON: LineLength
    }
}
