package org.apache.maven.plugin.assembly.archive.task;

/*
 * 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.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.plugin.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugin.assembly.InvalidAssemblerConfigurationException;
import org.apache.maven.plugin.assembly.archive.ArchiveCreationException;
import org.apache.maven.plugin.assembly.format.AssemblyFormattingException;
import org.apache.maven.plugin.assembly.model.DependencySet;
import org.apache.maven.plugin.assembly.model.FileSet;
import org.apache.maven.plugin.assembly.model.UnpackOptions;
import org.apache.maven.plugin.assembly.utils.AssemblyFormatUtils;
import org.apache.maven.plugin.assembly.utils.FilterUtils;
import org.apache.maven.plugin.assembly.utils.TypeConversionUtils;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.shared.artifact.filter.ScopeArtifactFilter;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.logging.Logger;

/**
 * @version $Id$
 */
public class AddDependencySetsTask
{

    private static final List<String> NON_ARCHIVE_DEPENDENCY_TYPES;

    static
    {
        final List<String> nonArch = new ArrayList<String>();

        nonArch.add( "pom" );

        NON_ARCHIVE_DEPENDENCY_TYPES = Collections.unmodifiableList( nonArch );
    }

    private final List<DependencySet> dependencySets;

    private final Logger logger;

    private final MavenProject project;

    private MavenProject moduleProject;

    private final MavenProjectBuilder projectBuilder;

    private String defaultOutputDirectory;

    private String defaultOutputFileNameMapping;

    private Artifact moduleArtifact;

    private final Set<Artifact> resolvedArtifacts;

    private final ArchiverManager archiverManager;

    public AddDependencySetsTask( final List<DependencySet> dependencySets, final Set<Artifact> resolvedArtifacts,
                                  final MavenProject project, final MavenProjectBuilder projectBuilder,
                                  final ArchiverManager archiverManager, final Logger logger )
    {
        this.dependencySets = dependencySets;
        this.resolvedArtifacts = resolvedArtifacts;
        this.project = project;
        this.projectBuilder = projectBuilder;
        this.archiverManager = archiverManager;
        this.logger = logger;
    }

    public void execute( final Archiver archiver, final AssemblerConfigurationSource configSource )
        throws ArchiveCreationException, AssemblyFormattingException, InvalidAssemblerConfigurationException
    {
        if ( ( dependencySets == null ) || dependencySets.isEmpty() )
        {
            logger.debug( "No dependency sets specified." );
            return;
        }

        @SuppressWarnings( "unchecked" )
        final List<Dependency> deps = project.getDependencies();
        if ( ( deps == null ) || deps.isEmpty() )
        {
            logger.debug( "Project " + project.getId() + " has no dependencies. Skipping dependency set addition." );
        }

        for ( final DependencySet dependencySet : dependencySets )
        {
            addDependencySet( dependencySet, archiver, configSource );
        }
    }

    void addDependencySet( final DependencySet dependencySet, final Archiver archiver,
                           final AssemblerConfigurationSource configSource )
        throws AssemblyFormattingException, ArchiveCreationException, InvalidAssemblerConfigurationException
    {
        logger.debug( "Processing DependencySet (output=" + dependencySet.getOutputDirectory() + ")" );

        if ( !dependencySet.isUseTransitiveDependencies() && dependencySet.isUseTransitiveFiltering() )
        {
            logger.warn( "DependencySet has nonsensical configuration: useTransitiveDependencies == false "
                + "AND useTransitiveFiltering == true. Transitive filtering flag will be ignored." );
        }

        final Set<Artifact> dependencyArtifacts = resolveDependencyArtifacts( dependencySet );

        boolean filterContents = false;
        final UnpackOptions opts = dependencySet.getUnpackOptions();
        if ( dependencySet.isUnpack() && opts != null && ( opts.isFiltered() || opts.getLineEnding() != null ) )
        {
            filterContents = true;
        }
        else if ( dependencyArtifacts.size() > 1 )
        {
            checkMultiArtifactOutputConfig( dependencySet );
        }

        logger.debug( "Adding " + dependencyArtifacts.size() + " dependency artifacts." );

        for ( final Artifact depArtifact : dependencyArtifacts )
        {
            MavenProject depProject;
            try
            {
                depProject =
                    projectBuilder.buildFromRepository( depArtifact, configSource.getRemoteRepositories(),
                                                        configSource.getLocalRepository() );
            }
            catch ( final ProjectBuildingException e )
            {
                logger.debug( "Error retrieving POM of module-dependency: " + depArtifact.getId() + "; Reason: "
                    + e.getMessage() + "\n\nBuilding stub project instance." );

                depProject = buildProjectStub( depArtifact );
            }

            if ( NON_ARCHIVE_DEPENDENCY_TYPES.contains( depArtifact.getType() ) )
            {
                addNonArchiveDependency( depArtifact, depProject, dependencySet, archiver, configSource );
            }
            else
            {
                if ( filterContents )
                {
                    addFilteredUnpackedArtifact( dependencySet, depArtifact, depProject, archiver, configSource );
                }
                else
                {
                    addNormalArtifact( dependencySet, depArtifact, depProject, archiver, configSource );
                }
            }
        }
    }

    private void checkMultiArtifactOutputConfig( final DependencySet dependencySet )
    {
        String dir = dependencySet.getOutputDirectory();
        if ( dir == null )
        {
            dir = defaultOutputDirectory;
        }

        String mapping = dependencySet.getOutputFileNameMapping();
        if ( mapping == null )
        {
            mapping = defaultOutputFileNameMapping;
        }

        if ( ( dir == null || !dir.contains( "${" ) ) && ( mapping == null || !mapping.contains( "${" ) ) )
        {
            logger.warn( "NOTE: Your assembly specifies a dependencySet that matches multiple artifacts, but specifies a concrete output format. "
                + "THIS MAY RESULT IN ONE OR MORE ARTIFACTS BEING OBSCURED!\n\nOutput directory: '"
                + dir
                + "'\nOutput filename mapping: '" + mapping + "'" );
        }
    }

    @SuppressWarnings( "ResultOfMethodCallIgnored" )
    private void addFilteredUnpackedArtifact( final DependencySet dependencySet, final Artifact depArtifact,
                                              final MavenProject depProject, final Archiver archiver,
                                              final AssemblerConfigurationSource configSource )
        throws ArchiveCreationException, AssemblyFormattingException
    {
        logger.debug( "Adding dependency artifact " + depArtifact.getId() + " after filtering the unpacked contents." );

        final StringBuilder sb =
            new StringBuilder().append( depArtifact.getGroupId() ).append( "_" ).append( depArtifact.getArtifactId() ).append( "_" ).append( depArtifact.getVersion() );

        final String classifier = depArtifact.getClassifier();
        if ( classifier != null )
        {
            sb.append( "_" ).append( classifier );
        }

        sb.append( "." ).append( depArtifact.getType() );

        final File dir = new File( configSource.getWorkingDirectory(), sb.toString() );
        if ( dir.exists() )
        {
            logger.debug( "NOT unpacking: " + depArtifact.getId() + ". Directory already exists in workdir:\n\t"
                + dir.getAbsolutePath() );
        }
        else
        {
            dir.mkdirs();

            UnArchiver unarchiver;
            try
            {
                unarchiver = archiverManager.getUnArchiver( depArtifact.getFile() );
            }
            catch ( final NoSuchArchiverException e )
            {
                throw new ArchiveCreationException( "Failed to retrieve un-archiver for: " + depArtifact.getId()
                    + ". Dependency filtering cannot proceed.", e );
            }

            unarchiver.setDestDirectory( dir );
            unarchiver.setOverwrite( true );
            unarchiver.setSourceFile( depArtifact.getFile() );
            unarchiver.setIgnorePermissions( configSource.isIgnorePermissions() );

            try
            {
                unarchiver.extract();
            }
            catch ( final ArchiverException e )
            {
                throw new ArchiveCreationException( "Failed to unpack dependency archive: " + depArtifact.getId()
                    + ". Dependency filtering cannot proceed.", e );
            }
        }

        final UnpackOptions opts = dependencySet.getUnpackOptions();

        final FileSet fs = new FileSet();
        fs.setDirectory( dir.getAbsolutePath() );
        fs.setDirectoryMode( dependencySet.getDirectoryMode() );
        fs.setExcludes( opts.getExcludes() );
        fs.setFileMode( dependencySet.getFileMode() );
        fs.setFiltered( opts.isFiltered() );
        fs.setIncludes( opts.getIncludes() );

        String outDir = dependencySet.getOutputDirectory();
        if ( outDir == null )
        {
            outDir = defaultOutputDirectory;
        }

        String filenameMapping = dependencySet.getOutputFileNameMapping();
        if ( filenameMapping == null )
        {
            filenameMapping = defaultOutputFileNameMapping;
        }

        filenameMapping =
            AssemblyFormatUtils.evaluateFileNameMapping( filenameMapping, depArtifact, configSource.getProject(),
                                                         moduleProject, moduleArtifact, depProject, configSource );

        final String outputLocation = new File( outDir, filenameMapping ).getPath();

        fs.setOutputDirectory( outputLocation );

        fs.setLineEnding( opts.getLineEnding() );
        fs.setUseDefaultExcludes( opts.isUseDefaultExcludes() );

        final AddFileSetsTask task = new AddFileSetsTask( fs );
        task.setProject( depProject );
        task.setModuleProject( moduleProject );
        task.setLogger( logger );

        task.execute( archiver, configSource );
    }

    private void addNormalArtifact( final DependencySet dependencySet, final Artifact depArtifact,
                                    final MavenProject depProject, final Archiver archiver,
                                    final AssemblerConfigurationSource configSource )
        throws AssemblyFormattingException, ArchiveCreationException
    {
        logger.debug( "Adding dependency artifact " + depArtifact.getId() + "." );

        final AddArtifactTask task = new AddArtifactTask( depArtifact, logger );

        task.setProject( depProject );
        task.setModuleProject( moduleProject );
        task.setModuleArtifact( moduleArtifact );
        task.setOutputDirectory( dependencySet.getOutputDirectory(), defaultOutputDirectory );
        task.setFileNameMapping( dependencySet.getOutputFileNameMapping(), defaultOutputFileNameMapping );

        final int dirMode = TypeConversionUtils.modeToInt( dependencySet.getDirectoryMode(), logger );
        if ( dirMode != -1 )
        {
            task.setDirectoryMode( dirMode );
        }

        final int fileMode = TypeConversionUtils.modeToInt( dependencySet.getFileMode(), logger );
        if ( fileMode != -1 )
        {
            task.setFileMode( fileMode );
        }

        task.setUnpack( dependencySet.isUnpack() );

        final UnpackOptions opts = dependencySet.getUnpackOptions();
        if ( dependencySet.isUnpack() && ( opts != null ) )
        {
            task.setIncludes( opts.getIncludes() );
            task.setExcludes( opts.getExcludes() );
        }

        task.execute( archiver, configSource );
    }

    private MavenProject buildProjectStub( final Artifact depArtifact )
    {
        final Model model = new Model();
        model.setGroupId( depArtifact.getGroupId() );
        model.setArtifactId( depArtifact.getArtifactId() );
        model.setVersion( depArtifact.getBaseVersion() );
        model.setPackaging( depArtifact.getType() );

        model.setDescription( "Stub for " + depArtifact.getId() );

        final MavenProject project = new MavenProject( model );
        project.setArtifact( depArtifact );

        return project;
    }

    Set<Artifact> resolveDependencyArtifacts( final DependencySet dependencySet )
        throws InvalidAssemblerConfigurationException
    {
        final Set<Artifact> dependencyArtifacts = new LinkedHashSet<Artifact>();
        if ( resolvedArtifacts != null )
        {
            dependencyArtifacts.addAll( resolvedArtifacts );
        }

        if ( dependencySet.isUseProjectArtifact() )
        {
            final Artifact projectArtifact = project.getArtifact();
            if ( ( projectArtifact != null ) && ( projectArtifact.getFile() != null ) )
            {
                dependencyArtifacts.add( projectArtifact );
            }
            else
            {
                logger.warn( "Cannot include project artifact: " + projectArtifact
                    + "; it doesn't have an associated file or directory." );
            }
        }

        if ( dependencySet.isUseProjectAttachments() )
        {
            @SuppressWarnings( "unchecked" )
            final List<Artifact> attachments = project.getAttachedArtifacts();
            if ( attachments != null )
            {
                for ( final Artifact attachment : attachments )
                {
                    if ( attachment.getFile() != null )
                    {
                        dependencyArtifacts.add( attachment );
                    }
                    else
                    {
                        logger.warn( "Cannot include attached artifact: " + project.getId() + " for project: "
                            + project.getId() + "; it doesn't have an associated file or directory." );
                    }
                }
            }
        }

        if ( dependencySet.isUseTransitiveFiltering() )
        {
            logger.debug( "Filtering dependency artifacts USING transitive dependency path information." );
        }
        else
        {
            logger.debug( "Filtering dependency artifacts WITHOUT transitive dependency path information." );
        }

        final ScopeArtifactFilter filter = new ScopeArtifactFilter( dependencySet.getScope() );

        FilterUtils.filterArtifacts( dependencyArtifacts, dependencySet.getIncludes(), dependencySet.getExcludes(),
                                     dependencySet.isUseStrictFiltering(), dependencySet.isUseTransitiveFiltering(),
                                     logger, filter );

        return dependencyArtifacts;
    }

    void addNonArchiveDependency( final Artifact depArtifact, final MavenProject depProject,
                                  final DependencySet dependencySet, final Archiver archiver,
                                  final AssemblerConfigurationSource configSource )
        throws AssemblyFormattingException, ArchiveCreationException
    {
        final File source = depArtifact.getFile();

        String outputDirectory = dependencySet.getOutputDirectory();

        outputDirectory =
            AssemblyFormatUtils.getOutputDirectory( outputDirectory, configSource.getProject(), moduleProject,
                                                    depProject, depProject.getBuild().getFinalName(), configSource );

        final String destName =
            AssemblyFormatUtils.evaluateFileNameMapping( dependencySet.getOutputFileNameMapping(), depArtifact,
                                                         configSource.getProject(), moduleProject, moduleArtifact,
                                                         depProject, configSource );

        String target;

        // omit the last char if ends with / or \\
        if ( outputDirectory.endsWith( "/" ) || outputDirectory.endsWith( "\\" ) )
        {
            target = outputDirectory + destName;
        }
        else
        {
            target = outputDirectory + "/" + destName;
        }

        try
        {
            final int mode = TypeConversionUtils.modeToInt( dependencySet.getFileMode(), logger );
            if ( mode > -1 )
            {
                archiver.addFile( source, target, mode );
            }
            else
            {
                archiver.addFile( source, target );
            }
        }
        catch ( final ArchiverException e )
        {
            throw new ArchiveCreationException( "Error adding file to archive: " + e.getMessage(), e );
        }
    }

    public List<DependencySet> getDependencySets()
    {
        return dependencySets;
    }

    public Logger getLogger()
    {
        return logger;
    }

    public void setDefaultOutputDirectory( final String defaultOutputDirectory )
    {
        this.defaultOutputDirectory = defaultOutputDirectory;
    }

    public void setDefaultOutputFileNameMapping( final String defaultOutputFileNameMapping )
    {
        this.defaultOutputFileNameMapping = defaultOutputFileNameMapping;
    }

    public void setModuleProject( final MavenProject moduleProject )
    {
        this.moduleProject = moduleProject;
    }

    public void setModuleArtifact( final Artifact moduleArtifact )
    {
        this.moduleArtifact = moduleArtifact;
    }
}
