/*
 * 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.
 */

package org.apache.axis2.maven2.mar;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;



/**
 * Abstract base class of all the mojos in the axis2-mar-maven-plugin.
 */
public abstract class AbstractMarMojo
    extends AbstractMojo
{

    /**
     * The projects base directory.
     */
    @Parameter(property = "project.basedir", required = true, readonly = true)
    protected File baseDir;
    
    /**
     * The maven project.
     */
    @Parameter(property = "project", required = true, readonly = true)
    protected MavenProject project;

    /**
     * The directory containing generated classes.
     */
    @Parameter(property = "project.build.outputDirectory", required = true)
    private File classesDirectory;

    /**
     * The directory where the mar is built.
     */
    @Parameter(defaultValue = "${project.build.directory}/mar", required = true)
    protected File marDirectory;

    /**
     * The location of the module.xml file.  If it is present in the META-INF
     * directory in src/main/resources with that name then it will automatically be 
     * included. Otherwise this parameter must be set.
     */
    @Parameter
    private File moduleXmlFile;

    /**
     * Additional file sets, which are being added to the archive.
     */
    @Parameter
    private FileSet[] fileSets;

    /**
     * Whether the dependency jars should be included in the mar
     */
    @Parameter(defaultValue = "true")
    private boolean includeDependencies;
    
    /**
     * Builds the exploded mar file.
     * @throws MojoExecutionException
     */
    protected void buildExplodedMar( )
        throws MojoExecutionException
    {
        getLog().debug( "Exploding mar..." );

        marDirectory.mkdirs();
        getLog().debug( "Assembling mar " + project.getArtifactId() + " in " + marDirectory );

        try
        {
            final File metaInfDir = new File( marDirectory, "META-INF" );
            final File libDir = new File(marDirectory, "lib");
            final File moduleFileTarget = new File( metaInfDir, "module.xml" );
            boolean existsBeforeCopyingClasses = moduleFileTarget.exists();

            if ( classesDirectory.exists() && ( !classesDirectory.equals( marDirectory ) ) )
            {
                FileUtils.copyDirectoryStructure( classesDirectory, marDirectory );
            }

            if ( fileSets != null )
            {
                for ( int i = 0;  i < fileSets.length;   i++ )
                {
                    FileSet fileSet = fileSets[i];
                    copyFileSet( fileSet, marDirectory );
                }
            }
            
            copyMetaInfFile( moduleXmlFile, moduleFileTarget, existsBeforeCopyingClasses, "module.xml file" );

            if(includeDependencies){
                Set<Artifact> artifacts = project.getArtifacts();
    
                List<String> duplicates = findDuplicates( artifacts );
    
                for (Artifact artifact : artifacts)
                {
                	String targetFileName = getDefaultFinalName( artifact );
    
                	getLog().debug( "Processing: " + targetFileName );
    
                	if ( duplicates.contains( targetFileName ) )
                	{
                		getLog().debug( "Duplicate found: " + targetFileName );
                		targetFileName = artifact.getGroupId() + "-" + targetFileName;
                		getLog().debug( "Renamed to: " + targetFileName );
                	}
    
                	// TODO: utilise appropriate methods from project builder
                	ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
                	if (filter.include( artifact ) )
                	{
                		String type = artifact.getType();
                		if ( "jar".equals( type ) )
                		{
                			copyFileIfModified( artifact.getFile(), new File( libDir, targetFileName ) );
                		}
                	}
                }
            }
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Could not explode mar...", e );
        }
    }

    /**
     * Searches a set of artifacts for duplicate filenames and returns a list of duplicates.
     *
     * @param artifacts set of artifacts
     * @return List of duplicated artifacts
     */
    private List<String> findDuplicates( Set<Artifact> artifacts )
    {
        List<String> duplicates = new ArrayList<String>();
        List<String> identifiers = new ArrayList<String>();
        for (Artifact artifact : artifacts)
        {
            String candidate = getDefaultFinalName( artifact );
            if ( identifiers.contains( candidate ) )
            {
                duplicates.add( candidate );
            }
            else
            {
                identifiers.add( candidate );
            }
        }
        return duplicates;
    }

    /**
     * Converts the filename of an artifact to artifactId-version.type format.
     *
     * @param artifact
     * @return converted filename of the artifact
     */
    private String getDefaultFinalName( Artifact artifact )
    {
        return artifact.getArtifactId() + "-" + artifact.getVersion() + "." +
            artifact.getArtifactHandler().getExtension();
    }

    /**
     * Copy file from source to destination only if source timestamp is later than the destination timestamp.
     * The directories up to <code>destination</code> will be created if they don't already exist.
     * <code>destination</code> will be overwritten if it already exists.
     *
     * @param source      An existing non-directory <code>File</code> to copy bytes from.
     * @param destination A non-directory <code>File</code> to write bytes to (possibly
     *                    overwriting).
     * @throws IOException                   if <code>source</code> does not exist, <code>destination</code> cannot be
     *                                       written to, or an IO error occurs during copying.
     * @throws java.io.FileNotFoundException if <code>destination</code> is a directory
     *                                       <p/>
     *                                       TO DO: Remove this method when Maven moves to plexus-utils version 1.4
     */
    private void copyFileIfModified( File source, File destination )
        throws IOException
    {
        // TO DO: Remove this method and use the method in WarFileUtils when Maven 2 changes
        // to plexus-utils 1.2.
        if ( destination.lastModified() < source.lastModified() )
        {
            FileUtils.copyFile( source.getCanonicalFile(), destination );
            // preserve timestamp
            destination.setLastModified( source.lastModified() );
        }
    }

    private void copyFileSet( FileSet fileSet, File targetDirectory )
        throws IOException
    {
        File dir = fileSet.getDirectory();
        if ( dir == null )
        {
            dir = baseDir;
        }
        File targetDir = targetDirectory;
        if ( fileSet.getOutputDirectory() != null )
        {
            targetDir = new File( targetDir, fileSet.getOutputDirectory() );
        }
        if ( targetDir.equals( dir ) )
        {
            return;
        }

        DirectoryScanner ds = new DirectoryScanner();
        ds.setBasedir( dir );
        if ( !fileSet.isSkipDefaultExcludes() )
        {
            ds.addDefaultExcludes();
        }
        final String[] excludes = fileSet.getExcludes();
        if ( excludes != null )
        {
            ds.setExcludes( excludes );
        }
        final String[] includes = fileSet.getIncludes();
        if ( includes != null )
        {
            ds.setIncludes( includes );
        }
        ds.scan();
        String[] files = ds.getIncludedFiles();
        for ( int i = 0;  i < files.length;  i++ )
        {
            File sourceFile = new File( dir, files[i] );
            File targetFile = new File( targetDir, files[i] );
            FileUtils.copyFile( sourceFile, targetFile );
        }
    }


    private void copyMetaInfFile( final File pSource, final File pTarget,
                                  final boolean pExistsBeforeCopying,
                                  final String pDescription )
        throws MojoExecutionException, IOException
    {
        if ( pSource != null  &&  pTarget != null )
        {
            if ( !pSource.exists() )
            {
                throw new MojoExecutionException( "The configured " + pDescription + " could not be found at "
                                                  + pSource );
            }

            if ( !pExistsBeforeCopying  &&  pTarget.exists() )
            {
                getLog().warn( "The configured " + pDescription + " overwrites another file from the classpath." );
            }

            FileUtils.copyFile( pSource, pTarget );
        }
    }
}
