package org.apache.maven.plugin.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.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.war.Overlay;
import org.codehaus.plexus.interpolation.InterpolationException;

/**
 * Handles the artifacts that needs to be packaged in the web application.
 *
 * @author Stephane Nicoll
 * 
 * @version $Id$
 */
public class ArtifactsPackagingTask
    extends AbstractWarPackagingTask
{

    public static final String TLD_PATH = "WEB-INF/tld/";

    public static final String SERVICES_PATH = "WEB-INF/services/";

    public static final String MODULES_PATH = "WEB-INF/modules/";

    public static final String EXTENSIONS_PATH = "WEB-INF/extensions/";

    private final Set<Artifact> artifacts;

    private final String id;


    public ArtifactsPackagingTask( Set<Artifact> artifacts, Overlay currentProjectOverlay )
    {
        this.artifacts = artifacts;
        this.id = currentProjectOverlay.getId();
    }


    public void performPackaging( WarPackagingContext context )
        throws MojoExecutionException
    {
        try
        {
        final ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
        final List<String> duplicates = findDuplicates( context, artifacts );

        for ( Artifact artifact : artifacts )
        {
            String targetFileName = getArtifactFinalName( context, artifact );

            context.getLog().debug( "Processing: " + targetFileName );

            if ( duplicates.contains( targetFileName ) )
            {
                context.getLog().debug( "Duplicate found: " + targetFileName );
                targetFileName = artifact.getGroupId() + "-" + targetFileName;
                context.getLog().debug( "Renamed to: " + targetFileName );
            }
            context.getWebappStructure().registerTargetFileName( artifact, targetFileName );

            if ( !artifact.isOptional() && filter.include( artifact ) )
            {
                try
                {
                    String type = artifact.getType();
                    if ( "tld".equals( type ) )
                    {
                        copyFile( id, context, artifact.getFile(), TLD_PATH + targetFileName );
                    }
                    else if ( "aar".equals( type ) )
                    {
                        copyFile( id, context, artifact.getFile(), SERVICES_PATH + targetFileName );
                    }
                    else if ( "mar".equals( type ) )
                    {
                        copyFile( id, context, artifact.getFile(), MODULES_PATH + targetFileName );
                    }
                    else if ( "xar".equals( type ) )
                    {
                        copyFile( id, context, artifact.getFile(), EXTENSIONS_PATH + targetFileName );
                    }
                    else if ( "jar".equals( type ) || "ejb".equals( type ) || "ejb-client".equals( type )
                        || "test-jar".equals( type ) || "bundle".equals( type ) )
                    {
                        copyFile( id, context, artifact.getFile(), LIB_PATH + targetFileName );
                    }
                    else if ( "par".equals( type ) )
                    {
                        targetFileName = targetFileName.substring( 0, targetFileName.lastIndexOf( '.' ) ) + ".jar";
                        copyFile( id, context, artifact.getFile(), LIB_PATH + targetFileName );
                    }
                    else if ( "war".equals( type ) )
                    {
                        // Nothing to do here, it is an overlay and it's already handled
                        context.getLog().debug( "war artifacts are handled as overlays, ignoring [" + artifact + "]" );
                    }
                    else if ( "zip".equals( type ) )
                    {
                        // Nothing to do here, it is an overlay and it's already handled
                        context.getLog().debug( "zip artifacts are handled as overlays, ignoring [" + artifact + "]" );
                    }
                    else
                    {
                        context.getLog().debug(
                            "Artifact of type [" + type + "] is not supported, ignoring [" + artifact + "]" );
                    }
                }
                catch ( IOException e )
                {
                    throw new MojoExecutionException( "Failed to copy file for artifact [" + artifact + "]", e );
                }
            }
        }
        }
        catch ( InterpolationException e )
        {
            throw new MojoExecutionException( e.getMessage(), e );
        }
    }

    /**
     * Searches a set of artifacts for duplicate filenames and returns a list
     * of duplicates.
     *
     * @param context   the packaging context
     * @param artifacts set of artifacts
     * @return List of duplicated artifacts as bundling file names
     */
    private List<String> findDuplicates( WarPackagingContext context, Set<Artifact> artifacts )
        throws InterpolationException
    {
        List<String> duplicates = new ArrayList<String>();
        List<String> identifiers = new ArrayList<String>();
        for ( Artifact artifact : artifacts )
        {
            String candidate = getArtifactFinalName( context, artifact );
            if ( identifiers.contains( candidate ) )
            {
                duplicates.add( candidate );
            }
            else
            {
                identifiers.add( candidate );
            }
        }
        return duplicates;
    }
}
