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 org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.war.Overlay;
import org.apache.maven.plugins.war.util.PathSet;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.io.IOException;

/**
 * Handles an overlay.
 *
 * @author Stephane Nicoll
 * @version $Id$
 */
public class OverlayPackagingTask
    extends AbstractWarPackagingTask
{
    private final Overlay overlay;

    /**
     * @param overlay {@link #overlay}
     * @param currentProjectOverlay current overlay.
     */
    public OverlayPackagingTask( Overlay overlay, Overlay currentProjectOverlay )
    {
        if ( overlay == null )
        {
            throw new NullPointerException( "overlay could not be null." );
        }
        if ( overlay.equals( currentProjectOverlay ) )
        {
            throw new IllegalStateException( "Could not handle the current project with this task." );
        }
        this.overlay = overlay;
    }

    /**
     * {@inheritDoc}
     */
    public void performPackaging( WarPackagingContext context )
        throws MojoExecutionException
    {
        context.getLog().debug( "OverlayPackagingTask performPackaging overlay.getTargetPath() "
                                    + overlay.getTargetPath() );
        if ( overlay.shouldSkip() )
        {
            context.getLog().info( "Skipping overlay [" + overlay + "]" );
        }
        else
        {
            try
            {
                context.getLog().info( "Processing overlay [" + overlay + "]" );

                // Step1: Extract if necessary
                final File tmpDir = unpackOverlay( context, overlay );

                // Step2: setup
                final PathSet includes = getFilesToIncludes( tmpDir, overlay.getIncludes(), overlay.getExcludes() );

                // Copy
                if ( null == overlay.getTargetPath() )
                {
                    copyFiles( overlay.getId(), context, tmpDir, includes, overlay.isFiltered() );
                }
                else
                {
                    // overlay.getTargetPath() must ended with /
                    // if not we add it
                    String targetPath = overlay.getTargetPath();
                    if ( !targetPath.endsWith( "/" ) )
                    {
                        targetPath = targetPath + "/";
                    }
                    copyFiles( overlay.getId(), context, tmpDir, includes, targetPath, overlay.isFiltered() );
                }
            }
            catch ( IOException e )
            {
                throw new MojoExecutionException( "Failed to copy file for overlay [" + overlay + "]", e );
            }
        }
    }

    /**
     * Unpacks the specified overlay.
     * <p/>
     * Makes sure to skip the unpack process if the overlay has already been unpacked.
     *
     * @param context the packaging context
     * @param overlay the overlay
     * @return the directory containing the unpacked overlay
     * @throws MojoExecutionException if an error occurred while unpacking the overlay
     */
    protected File unpackOverlay( WarPackagingContext context, Overlay overlay )
        throws MojoExecutionException
    {
        final File tmpDir = getOverlayTempDirectory( context, overlay );

        // TODO: not sure it's good, we should reuse the markers of the dependency plugin
        if ( FileUtils.sizeOfDirectory( tmpDir ) == 0
            || overlay.getArtifact().getFile().lastModified() > tmpDir.lastModified() )
        {
            doUnpack( context, overlay.getArtifact().getFile(), tmpDir );
        }
        else
        {
            context.getLog().debug( "Overlay [" + overlay + "] was already unpacked" );
        }
        return tmpDir;
    }

    /**
     * Returns the directory to use to unpack the specified overlay.
     *
     * @param context the packaging context
     * @param overlay the overlay
     * @return the temp directory for the overlay
     */
    protected File getOverlayTempDirectory( WarPackagingContext context, Overlay overlay )
    {
        final File groupIdDir = new File( context.getOverlaysWorkDirectory(), overlay.getGroupId() );
        if ( !groupIdDir.exists() )
        {
            groupIdDir.mkdir();
        }
        String directoryName = overlay.getArtifactId();
        if ( overlay.getClassifier() != null )
        {
            directoryName = directoryName + "-" + overlay.getClassifier();
        }
        final File result = new File( groupIdDir, directoryName );
        if ( !result.exists() )
        {
            result.mkdirs();
        }
        return result;
    }
}
