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
 */
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, context.isFailOnMissingWebXml() );

        handleClassesDirectory( context );

        handleArtifacts( context );

        if ( !context.getWebappDirectory().mkdirs() )
        {
            for ( String resource : context.getOutdatedResources() )
            {
                new File( context.getWebappDirectory(), resource ).delete();
            }
        }
    }

    /**
     * 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
    {
        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
     * @param failOnMissingWebXml if build should fail if web.xml is not found
     * @throws MojoFailureException if the web.xml is specified but does not exist and failOnMissingWebXml is true
     * @throws MojoExecutionException if an error occurred while copying the descriptors
     */
    protected void handleDeploymentDescriptors( WarPackagingContext context, File webinfDir, File metainfDir,
                                                Boolean failOnMissingWebXml )
        throws MojoFailureException, MojoExecutionException
    {
        try
        {
            if ( webXml != null && StringUtils.isNotEmpty( webXml.getName() ) )
            {
                if ( !webXml.exists()
                        && ( failOnMissingWebXml == null || Boolean.TRUE.equals( failOnMissingWebXml ) ) )
                {
                    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 )
        {
            if ( failOnMissingWebXml == null || Boolean.TRUE.equals( failOnMissingWebXml ) )
            {
                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
    }
}
