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 org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.war.util.WebappStructure;

import java.io.File;

/**
 * Analyzes the dependencies of the project with its previous state and update
 * the target directory accordingly.
 *
 * @author Stephane Nicoll
 * 
 * @version $Id$
 */
public class DependenciesAnalysisPackagingTask
    extends AbstractWarPackagingTask
{

    public void performPackaging( final WarPackagingContext context )
        throws MojoExecutionException, MojoFailureException
    {

        context.getWebappStructure().analyseDependencies( new DependenciesAnalysisCallbackImpl( context ) );

    }

    protected void handleDependency( WarPackagingContext context, Dependency dependency, String notBundledMessage,
                                     String warOrZipMessage, String standardMessage, boolean removeFile )
    {
        if ( Artifact.SCOPE_PROVIDED.equals( dependency.getScope() )
            || Artifact.SCOPE_TEST.equals( dependency.getScope() ) || dependency.isOptional() )
        {
            context.getLog().debug( notBundledMessage );
        }
        else {
            handleDependencyScope( context, dependency, warOrZipMessage, standardMessage, removeFile );
        }
    }

    protected void handleDependencyScope( WarPackagingContext context, Dependency dependency, String warOrZipMessage,
                                          String standardMessage, boolean removeFile )
    {
        if ( "war".equals( dependency.getType() ) || "zip".equals( dependency.getType() ) )
        {
            context.getLog().warn( warOrZipMessage );
        }
        else if ( "tld".equals( dependency.getType() ) || "aar".equals( dependency.getType() )
            || "mar".equals( dependency.getType() ) || "xar".equals( dependency.getType() )
            || "jar".equals( dependency.getType() ) || "ejb".equals( dependency.getType() )
            || "ejb-client".equals( dependency.getType() ) || "test-jar".equals( dependency.getType() )
            || "par".equals( dependency.getType() ) )
        {
            context.getLog().info( standardMessage );
            if ( removeFile )
            {
                removeDependency( context, dependency );
            }
        }
    }

    private void removeDependency( WarPackagingContext context, Dependency dependency )
    {
        final String targetFileName = context.getWebappStructure().getCachedTargetFileName( dependency );
        if ( targetFileName != null )
        {
            final String type = dependency.getType();
            File targetFile = null;
            if ( "tld".equals( type ) )
            {
                targetFile = new File( context.getWebappDirectory(), ArtifactsPackagingTask.TLD_PATH + targetFileName );
            }
            else if ( "aar".equals( type ) )
            {
                targetFile =
                    new File( context.getWebappDirectory(), ArtifactsPackagingTask.SERVICES_PATH + targetFileName );
            }
            else if ( "mar".equals( type ) )
            {
                targetFile =
                    new File( context.getWebappDirectory(), ArtifactsPackagingTask.MODULES_PATH + targetFileName );
            }
            else if ( "xar".equals( type ) )
            {
                targetFile =
                    new File( context.getWebappDirectory(), ArtifactsPackagingTask.EXTENSIONS_PATH + targetFileName );
            }
            else if ( "jar".equals( type ) || "ejb".equals( type ) || "ejb-client".equals( type )
                || "test-jar".equals( type ) )
            {
                targetFile = new File( context.getWebappDirectory(), LIB_PATH + targetFileName );
            }
            else if ( "par".equals( type ) )
            {
                String targetFileName2 = targetFileName.substring( 0, targetFileName.lastIndexOf( '.' ) ) + ".jar";
                targetFile = new File( context.getWebappDirectory(), LIB_PATH + targetFileName2 );
            }

            // now remove
            if ( targetFile == null )
            {
                context.getLog().error( "Could not get file from dependency [" + dependency + "]" );
            }
            else if ( targetFile.exists() )
            {
                context.getLog().debug( "Removing file [" + targetFile.getAbsolutePath() + "]" );
                targetFile.delete();
            }
            else
            {
                context.getLog().warn( "File to remove [" + targetFile.getAbsolutePath() + "] has not been found" );
            }
        }
        else
        {
            context.getLog().warn( "Could not retrieve the target file name of dependency [" + dependency + "]" );
        }
    }


    class DependenciesAnalysisCallbackImpl
        implements WebappStructure.DependenciesAnalysisCallback
    {
        private final WarPackagingContext context;

        DependenciesAnalysisCallbackImpl( WarPackagingContext context )
        {
            this.context = context;
        }

        public void unchangedDependency( Dependency dependency )
        {
            context.getLog().debug( "Dependency [" + dependency + "] has not changed since last build." );
        }

        public void newDependency( Dependency dependency )
        {
            context.getLog().debug( "New dependency [" + dependency + "]." );
        }

        public void removedDependency( Dependency dependency )
        {
            handleDependency( context, dependency, "Dependency [" + dependency
                + "] has been removed from the project but it was not bundled anyway.", "Dependency [" + dependency
                + "] has been removed from the project. If it was included in the build as an overlay, "
                + "consider cleaning the target directory of the project (mvn clean)", "Dependency [" + dependency
                + "] has been removed from the project.", true );
        }

        public void updatedVersion( Dependency dependency, String previousVersion )
        {
            handleDependency( context, dependency, "Version of dependency [" + dependency + "] has changed ("
                + previousVersion + " -> " + dependency.getVersion() + ") but it was not bundled anyway.",
                                                   "Version of dependency [" + dependency + "] has changed ("
                                                       + previousVersion + " -> " + dependency.getVersion()
                                                       + "). If it was included in the build as an overlay, "
                                                       + "consider "
                                                       + "cleaning the target directory of the project (mvn clean)",
                                                   "Version of dependency [" + dependency + "] has changed ("
                                                       + previousVersion + " -> " + dependency.getVersion() + ").",
                                                   true );
        }

        public void updatedScope( Dependency dependency, String previousScope )
        {
            if ( Artifact.SCOPE_PROVIDED.equals( dependency.getScope() ) || Artifact.SCOPE_TEST.equals(
                dependency.getScope() )
                && ( !Artifact.SCOPE_PROVIDED.equals( previousScope )
                && !Artifact.SCOPE_TEST.equals( previousScope ) ) )
            {
                // It's now provided or test so it should be removed
                handleDependencyScope( context, dependency, "Scope of dependency [" + dependency + "] has changed ("
                    + previousScope + " -> " + dependency.getScope()
                    + "). If it was included in the build as an overlay, "
                    + "consider cleaning the target directory of the project (mvn clean)", "Scope of dependency ["
                    + dependency + "] has changed (" + previousScope + " -> " + dependency.getScope() + ").", true );
            }

        }


        public void updatedOptionalFlag( Dependency dependency, boolean previousOptional )
        {
            if ( !previousOptional && dependency.isOptional() )
            {
                // It wasn't optional but now it is anymore
                handleDependency( context, dependency,
                                  "Dependency [" + dependency + "] is now optional but it was not bundled anyway.",
                                  "Dependency [" + dependency
                                      + "] is now optional. If it was included in the build as an overlay, "
                                      + "consider cleaning the target directory of the project (mvn clean)",
                                  "Dependency [" + dependency + "] is now optional", true );


            }
        }

        public void updatedUnknown( Dependency dependency, Dependency previousDep )
        {
            handleDependency( context, dependency, "Dependency [" + dependency + "] has changed (was " + previousDep
                + ") but it was not bundled anyway.", "Dependency [" + dependency + "] has changed (was " + previousDep
                + "). If it was included in the build as an overlay, " + "consider "
                + "cleaning the target directory of the project (mvn clean)", "Dependency [" + dependency
                + "] has changed (was " + previousDep + ").", true );
        }

    }

}
