package org.apache.maven.plugins.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.nio.charset.Charset;
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.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
import org.apache.maven.plugins.assembly.format.ReaderFormatter;
import org.apache.maven.plugins.assembly.model.DependencySet;
import org.apache.maven.plugins.assembly.model.UnpackOptions;
import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
import org.apache.maven.plugins.assembly.utils.FilterUtils;
import org.apache.maven.plugins.assembly.utils.TypeConversionUtils;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.ProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingResult;
import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter;
import org.apache.maven.shared.artifact.filter.resolve.transform.ArtifactIncludeFilterTransformer;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
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<>();

        nonArch.add( "pom" );

        NON_ARCHIVE_DEPENDENCY_TYPES = Collections.unmodifiableList( nonArch );
    }

    private final List<DependencySet> dependencySets;

    private final Logger logger;

    private final MavenProject project;

    private final ProjectBuilder projectBuilder1;

    private final Set<Artifact> resolvedArtifacts;

    private MavenProject moduleProject;

    private String defaultOutputDirectory;

    private String defaultOutputFileNameMapping;

    private Artifact moduleArtifact;


    public AddDependencySetsTask( final List<DependencySet> dependencySets, final Set<Artifact> resolvedArtifacts,
                                  final MavenProject project, ProjectBuilder projectBuilder, final Logger logger )
    {
        this.dependencySets = dependencySets;
        this.resolvedArtifacts = resolvedArtifacts;
        this.project = project;
        this.projectBuilder1 = projectBuilder;
        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;
        }

        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 );

        if ( !unpackTransformsContent( dependencySet ) && dependencyArtifacts.size() > 1 )
        {
            checkMultiArtifactOutputConfig( dependencySet );
        }

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

        InputStreamTransformer fileSetTransformers =
            isUnpackWithOptions( dependencySet )
                ? ReaderFormatter.getFileSetTransformers( configSource, dependencySet.getUnpackOptions().isFiltered(),
                                                          dependencySet.getUnpackOptions().getLineEnding() )
                : null;

        for ( final Artifact depArtifact : dependencyArtifacts )
        {
            ProjectBuildingRequest pbr = getProjectBuildingRequest( configSource );
            MavenProject depProject;
            try
            {
                ProjectBuildingResult build = projectBuilder1.build( depArtifact, pbr );
                depProject = build.getProject();
            }
            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
            {
                addNormalArtifact( dependencySet, depArtifact, depProject, archiver, configSource,
                                   fileSetTransformers );
            }
        }
    }

    private ProjectBuildingRequest getProjectBuildingRequest( AssemblerConfigurationSource configSource )
    {
        return configSource.getMavenSession().getProjectBuildingRequest();
    }

    private boolean isUnpackWithOptions( DependencySet dependencySet )
    {
        return dependencySet.isUnpack() && dependencySet.getUnpackOptions() != null;
    }

    private boolean unpackTransformsContent( DependencySet dependencySet )
    {
        return isUnpackWithOptions( dependencySet ) && isContentModifyingOption( dependencySet.getUnpackOptions() );
    }

    private boolean isContentModifyingOption( UnpackOptions opts )
    {
        return ( opts.isFiltered() || opts.getLineEnding() != null );
    }

    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\n" + "Output directory: '" + dir + "'\nOutput filename mapping: '" + mapping
                             + "'" );
        }
    }

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

        String encoding = isUnpackWithOptions( dependencySet ) ? dependencySet.getUnpackOptions().getEncoding() : null;
        Charset charset = encoding != null ? Charset.forName( encoding ) : null;
        final AddArtifactTask task = new AddArtifactTask( depArtifact, logger, fileSetTransformers, charset );

        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 ( isUnpackWithOptions( dependencySet ) )
        {
            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<>();
        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() )
        {
            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 ScopeFilter scopeFilter = FilterUtils.newScopeFilter( dependencySet.getScope() );

        final ArtifactFilter filter = new ArtifactIncludeFilterTransformer().transform( scopeFilter );
        
        FilterUtils.filterArtifacts( dependencyArtifacts, dependencySet.getIncludes(), dependencySet.getExcludes(),
                                     dependencySet.isUseStrictFiltering(), dependencySet.isUseTransitiveFiltering(),
                                     logger, filter );

        return dependencyArtifacts;
    }

    private 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();

        FixedStringSearchInterpolator moduleProjectInterpolator =
            AssemblyFormatUtils.moduleProjectInterpolator( moduleProject );
        FixedStringSearchInterpolator artifactProjectInterpolator =
            AssemblyFormatUtils.artifactProjectInterpolator( depProject );
        outputDirectory =
            AssemblyFormatUtils.getOutputDirectory( outputDirectory, depProject.getBuild().getFinalName(), configSource,
                                                    moduleProjectInterpolator, artifactProjectInterpolator );

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

        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;
    }
}
