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 org.apache.maven.artifact.Artifact;
import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
import org.apache.maven.plugins.assembly.utils.TypeConversionUtils;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.util.DefaultArchivedFileSet;
import org.codehaus.plexus.archiver.util.DefaultFileSet;
import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

/**
 *
 */
public class AddArtifactTask
{

    public static final String[] DEFAULT_INCLUDES_ARRAY = { "**/*" };

    private final Artifact artifact;

    private final Logger logger;

    private final InputStreamTransformer transformer;

    private final Charset encoding;

    private int directoryMode = -1;

    private int fileMode = -1;

    private boolean unpack = false;

    private List<String> includes;

    private List<String> excludes;

    private MavenProject project;

    private MavenProject moduleProject;

    private Artifact moduleArtifact;

    private String outputDirectory;

    private String outputFileNameMapping;

    public AddArtifactTask( final Artifact artifact, final Logger logger, InputStreamTransformer transformer,
                            Charset encoding )
    {
        this.artifact = artifact;
        this.logger = logger;
        this.transformer = transformer;
        this.encoding = encoding;
    }

    public AddArtifactTask( final Artifact artifact, final Logger logger, Charset encoding )
    {
        this( artifact, logger, null, encoding );
    }

    public void execute( final Archiver archiver, final AssemblerConfigurationSource configSource )
        throws ArchiveCreationException, AssemblyFormattingException
    {
        if ( artifactIsArchiverDestination( archiver ) )
        {
            artifact.setFile( moveArtifactSomewhereElse( configSource ) );
        }

        String destDirectory =
            AssemblyFormatUtils.getOutputDirectory( outputDirectory, configSource.getFinalName(), configSource,
                                                    AssemblyFormatUtils.moduleProjectInterpolator( moduleProject ),
                                                    AssemblyFormatUtils.artifactProjectInterpolator( project ) );

        boolean fileModeSet = false;
        boolean dirModeSet = false;

        final int oldDirMode = archiver.getOverrideDirectoryMode();
        final int oldFileMode = archiver.getOverrideFileMode();

        if ( fileMode != -1 )
        {
            archiver.setFileMode( fileMode );
            fileModeSet = true;
        }

        if ( directoryMode != -1 )
        {
            archiver.setDirectoryMode( directoryMode );
            dirModeSet = true;
        }
        try
        {

            if ( unpack )
            {
                unpacked( archiver, destDirectory );
            }
            else
            {
                asFile( archiver, configSource, destDirectory );
            }
        }
        finally
        {
            if ( dirModeSet )
            {
                archiver.setDirectoryMode( oldDirMode );
            }

            if ( fileModeSet )
            {
                archiver.setFileMode( oldFileMode );
            }
        }

    }

    private void asFile( Archiver archiver, AssemblerConfigurationSource configSource, String destDirectory )
        throws AssemblyFormattingException, ArchiveCreationException
    {
        final String tempMapping =
            AssemblyFormatUtils.evaluateFileNameMapping( outputFileNameMapping, artifact, configSource.getProject(),
                                                         moduleArtifact, configSource,
                                                         AssemblyFormatUtils.moduleProjectInterpolator( moduleProject ),
                                                         AssemblyFormatUtils.artifactProjectInterpolator( project ) );

        final String outputLocation = destDirectory + tempMapping;

        try
        {
            final File artifactFile = artifact.getFile();

            logger.debug(
                "Adding artifact: " + artifact.getId() + " with file: " + artifactFile + " to assembly location: "
                    + outputLocation + "." );

            if ( fileMode != -1 )
            {
                archiver.addFile( artifactFile, outputLocation, fileMode );
            }
            else
            {
                archiver.addFile( artifactFile, outputLocation );
            }
        }
        catch ( final ArchiverException e )
        {
            throw new ArchiveCreationException(
                "Error adding file '" + artifact.getId() + "' to archive: " + e.getMessage(), e );
        }
    }

    private void unpacked( Archiver archiver, String destDirectory )
        throws ArchiveCreationException
    {
        String outputLocation = destDirectory;

        if ( ( outputLocation.length() > 0 ) && !outputLocation.endsWith( "/" ) )
        {
            outputLocation += "/";
        }

        String[] includesArray = TypeConversionUtils.toStringArray( includes );
        if ( includesArray == null )
        {
            includesArray = DEFAULT_INCLUDES_ARRAY;
        }
        final String[] excludesArray = TypeConversionUtils.toStringArray( excludes );

        try
        {

            final File artifactFile = artifact.getFile();
            if ( artifactFile == null )
            {
                logger.warn(
                    "Skipping artifact: " + artifact.getId() + "; it does not have an associated file or directory." );
            }
            else if ( artifactFile.isDirectory() )
            {
                logger.debug( "Adding artifact directory contents for: " + artifact + " to: " + outputLocation );

                DefaultFileSet fs = DefaultFileSet.fileSet( artifactFile );
                fs.setIncludes( includesArray );
                fs.setExcludes( excludesArray );
                fs.setPrefix( outputLocation );
                fs.setStreamTransformer( transformer );
                archiver.addFileSet( fs );
            }
            else
            {
                logger.debug( "Unpacking artifact contents for: " + artifact + " to: " + outputLocation );
                logger.debug( "includes:\n" + StringUtils.join( includesArray, "\n" ) + "\n" );
                logger.debug(
                    "excludes:\n" + ( excludesArray == null ? "none" : StringUtils.join( excludesArray, "\n" ) )
                        + "\n" );
                DefaultArchivedFileSet afs = DefaultArchivedFileSet.archivedFileSet( artifactFile );
                afs.setIncludes( includesArray );
                afs.setExcludes( excludesArray );
                afs.setPrefix( outputLocation );
                afs.setStreamTransformer( transformer );
                archiver.addArchivedFileSet( afs, encoding );
            }
        }
        catch ( final ArchiverException e )
        {
            throw new ArchiveCreationException(
                "Error adding file-set for '" + artifact.getId() + "' to archive: " + e.getMessage(), e );
        }
    }

    private File moveArtifactSomewhereElse( AssemblerConfigurationSource configSource )
        throws ArchiveCreationException
    {
        final File tempRoot = configSource.getTemporaryRootDirectory();
        final File tempArtifactFile = new File( tempRoot, artifact.getFile().getName() );

        logger.warn( "Artifact: " + artifact.getId() + " references the same file as the assembly destination file. "
                         + "Moving it to a temporary location for inclusion." );
        try
        {
            FileUtils.copyFile( artifact.getFile(), tempArtifactFile );
        }
        catch ( final IOException e )
        {
            throw new ArchiveCreationException(
                "Error moving artifact file: '" + artifact.getFile() + "' to temporary location: " + tempArtifactFile
                    + ". Reason: " + e.getMessage(), e );
        }
        return tempArtifactFile;
    }

    private boolean artifactIsArchiverDestination( Archiver archiver )
    {
        return ( ( artifact.getFile() != null ) && ( archiver.getDestFile() != null ) ) && artifact.getFile().equals(
            archiver.getDestFile() );
    }

    public void setDirectoryMode( final int directoryMode )
    {
        this.directoryMode = directoryMode;
    }

    public void setFileMode( final int fileMode )
    {
        this.fileMode = fileMode;
    }

    public void setExcludes( final List<String> excludes )
    {
        this.excludes = excludes;
    }

    public void setIncludes( final List<String> includes )
    {
        this.includes = includes;
    }

    public void setUnpack( final boolean unpack )
    {
        this.unpack = unpack;
    }

    public void setProject( final MavenProject project )
    {
        this.project = project;
    }

    public void setOutputDirectory( final String outputDirectory )
    {
        this.outputDirectory = outputDirectory;
    }

    public void setFileNameMapping( final String outputFileNameMapping )
    {
        this.outputFileNameMapping = outputFileNameMapping;
    }

    public void setOutputDirectory( final String outputDirectory, final String defaultOutputDirectory )
    {
        setOutputDirectory( outputDirectory == null ? defaultOutputDirectory : outputDirectory );
    }

    public void setFileNameMapping( final String outputFileNameMapping, final String defaultOutputFileNameMapping )
    {
        setFileNameMapping( outputFileNameMapping == null ? defaultOutputFileNameMapping : outputFileNameMapping );
    }

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

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

}
