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.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.war.Overlay;
import org.apache.maven.plugins.war.util.ClassesPackager;
import org.apache.maven.plugins.war.util.PathSet;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.interpolation.InterpolationException;

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

/**
 * Handles the classes directory that needs to be packaged in the web application.
 * 
 * Based on the {@link WarPackagingContext#archiveClasses()} flag the resources either copied into to
 * <tt>WEB-INF/classes</tt> directory or archived in a jar within the <tt>WEB-INF/lib</tt> directory.
 *
 * @author Stephane Nicoll
 * @version $Id$
 */
public class ClassesPackagingTask
    extends AbstractWarPackagingTask
{
    private final Overlay currentProjectOverlay;

    /**
     * @param currentProjectOverlay {@link #currentProjectOverlay}
     */
    public ClassesPackagingTask( Overlay currentProjectOverlay )
    {
        this.currentProjectOverlay = currentProjectOverlay;
    }

    /**
     * {@inheritDoc}
     */
    public void performPackaging( WarPackagingContext context )
        throws MojoExecutionException
    {
        final File webappClassesDirectory = new File( context.getWebappDirectory(), CLASSES_PATH );
        if ( !webappClassesDirectory.exists() )
        {
            webappClassesDirectory.mkdirs();
        }

        if ( context.getClassesDirectory().exists() && !context.getClassesDirectory().equals( webappClassesDirectory ) )
        {
            if ( context.archiveClasses() )
            {
                generateJarArchive( context );
            }
            else
            {
                final PathSet sources = getFilesToIncludes( context.getClassesDirectory(), null, null );
                try
                {
                    copyFiles( currentProjectOverlay.getId(), context, context.getClassesDirectory(), sources,
                               CLASSES_PATH, false );
                }
                catch ( IOException e )
                {
                    throw new MojoExecutionException( "Could not copy webapp classes ["
                        + context.getClassesDirectory().getAbsolutePath() + "]", e );
                }
            }
        }
    }

    /**
     * @param context The warPackingContext.
     * @throws MojoExecutionException In case of an error.
     */
    protected void generateJarArchive( WarPackagingContext context )
        throws MojoExecutionException
    {
        MavenProject project = context.getProject();
        ArtifactFactory factory = context.getArtifactFactory();
        Artifact artifact =
            factory.createBuildArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), "jar" );
        String archiveName;
        try
        {
            archiveName = getArtifactFinalName( context, artifact );
        }
        catch ( InterpolationException e )
        {
            throw new MojoExecutionException( "Could not get the final name of the artifact [" + artifact.getGroupId()
                + ":" + artifact.getArtifactId() + ":" + artifact.getVersion() + "]", e );
        }
        final String targetFilename = LIB_PATH + archiveName;

        if ( context.getWebappStructure().registerFile( currentProjectOverlay.getId(), targetFilename ) )
        {
            final File libDirectory = new File( context.getWebappDirectory(), LIB_PATH );
            final File jarFile = new File( libDirectory, archiveName );
            final ClassesPackager packager = new ClassesPackager();
            packager.packageClasses( context.getClassesDirectory(), jarFile, context.getJarArchiver(),
                                     context.getSession(), project, context.getArchive() );
        }
        else
        {
            context.getLog().warn( "Could not generate archive classes file [" + targetFilename
                                       + "] has already been copied." );
        }
    }
}
