package org.apache.maven.plugins.assembly.archive;

/*
 * 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.plugin.DebugConfigurationListener;
import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
import org.apache.maven.plugins.assembly.archive.archiver.AssemblyProxyArchiver;
import org.apache.maven.plugins.assembly.archive.phase.AssemblyArchiverPhase;
import org.apache.maven.plugins.assembly.archive.phase.AssemblyArchiverPhaseComparator;
import org.apache.maven.plugins.assembly.artifact.DependencyResolutionException;
import org.apache.maven.plugins.assembly.filter.ComponentsXmlArchiverFileFilter;
import org.apache.maven.plugins.assembly.filter.ContainerDescriptorHandler;
import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
import org.apache.maven.plugins.assembly.interpolation.AssemblyExpressionEvaluator;
import org.apache.maven.plugins.assembly.model.Assembly;
import org.apache.maven.plugins.assembly.model.ContainerDescriptorHandlerConfig;
import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.archiver.ArchiveFinalizer;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.diags.DryRunArchiver;
import org.codehaus.plexus.archiver.filters.JarSecurityFileSelector;
import org.codehaus.plexus.archiver.jar.JarArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.archiver.tar.TarArchiver;
import org.codehaus.plexus.archiver.tar.TarLongFileMode;
import org.codehaus.plexus.archiver.war.WarArchiver;
import org.codehaus.plexus.archiver.zip.AbstractZipArchiver;
import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
import org.codehaus.plexus.component.configurator.ComponentConfigurator;
import org.codehaus.plexus.component.configurator.ConfigurationListener;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.components.io.fileselectors.FileSelector;
import org.codehaus.plexus.configuration.PlexusConfiguration;
import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * Controller component designed to organize the many activities involved in creating an assembly archive. This includes
 * locating and configuring {@link Archiver} instances, executing multiple {@link org.apache.maven.plugins.assembly
 * .archive.phase.AssemblyArchiverPhase} instances to
 * interpret the various sections of the assembly descriptor and determine which files to add, and other associated
 * activities.
 *
 *
 */
@Component( role = AssemblyArchiver.class, instantiationStrategy = "per-lookup" )
public class DefaultAssemblyArchiver
    extends AbstractLogEnabled
    implements AssemblyArchiver, Contextualizable
{

    @Requirement
    private ArchiverManager archiverManager;

    @Requirement( role = AssemblyArchiverPhase.class )
    private List<AssemblyArchiverPhase> assemblyPhases;

    @SuppressWarnings( "MismatchedQueryAndUpdateOfCollection" )
    @Requirement( role = ContainerDescriptorHandler.class )
    private Map<String, ContainerDescriptorHandler> containerDescriptorHandlers;

    private PlexusContainer container;

    @SuppressWarnings( "UnusedDeclaration" )
    public DefaultAssemblyArchiver()
    {
    }

    // introduced for testing.

    /**
     * @param archiverManager The archive manager.
     * @param assemblyPhases  The list of {@link AssemblyArchiverPhase}
     */
    protected DefaultAssemblyArchiver( final ArchiverManager archiverManager,
                                       final List<AssemblyArchiverPhase> assemblyPhases )
    {
        this.archiverManager = archiverManager;
        this.assemblyPhases = assemblyPhases;
    }

    private List<AssemblyArchiverPhase> sortedPhases()
    {
        List<AssemblyArchiverPhase> sorted = new ArrayList<>( assemblyPhases );
        Collections.sort( sorted, new AssemblyArchiverPhaseComparator() );
        return sorted;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public File createArchive( final Assembly assembly, final String fullName, final String format,
                               final AssemblerConfigurationSource configSource, boolean recompressZippedFiles,
                               String mergeManifestMode )
        throws ArchiveCreationException, AssemblyFormattingException, InvalidAssemblerConfigurationException
    {
        validate( assembly );

        String filename = fullName;
        if ( !configSource.isIgnoreDirFormatExtensions() || !format.startsWith( "dir" ) )
        {
            filename += "." + format;
        }

        AssemblyFileUtils.verifyTempDirectoryAvailability( configSource.getTemporaryRootDirectory() );

        final File outputDirectory = configSource.getOutputDirectory();

        final File destFile = new File( outputDirectory, filename );

        try
        {
            final String finalName = configSource.getFinalName();
            final String specifiedBasedir = assembly.getBaseDirectory();

            String basedir = finalName;

            if ( specifiedBasedir != null )
            {
                basedir = AssemblyFormatUtils.getOutputDirectory( specifiedBasedir, finalName, configSource,
                                                                  AssemblyFormatUtils.moduleProjectInterpolator(
                                                                      configSource.getProject() ),
                                                                  AssemblyFormatUtils.artifactProjectInterpolator(
                                                                      null ) );
            }

            final List<ContainerDescriptorHandler> containerHandlers =
                selectContainerDescriptorHandlers( assembly.getContainerDescriptorHandlers(), configSource );

            final Archiver archiver =
                createArchiver( format, assembly.isIncludeBaseDirectory(), basedir, configSource, containerHandlers,
                                recompressZippedFiles, mergeManifestMode );

            archiver.setDestFile( destFile );

            for ( AssemblyArchiverPhase phase : sortedPhases() )
            {
                phase.execute( assembly, archiver, configSource );
            }

            archiver.createArchive();
        }
        catch ( final ArchiverException | IOException e )
        {
            throw new ArchiveCreationException(
                "Error creating assembly archive " + assembly.getId() + ": " + e.getMessage(), e );
        }
        catch ( final NoSuchArchiverException e )
        {
            throw new ArchiveCreationException(
                "Unable to obtain archiver for extension '" + format + "', for assembly: '" + assembly.getId() + "'",
                e );
        }
        catch ( final DependencyResolutionException e )
        {
            throw new ArchiveCreationException(
                "Unable to resolve dependencies for assembly '" + assembly.getId() + "'", e );
        }

        return destFile;
    }

    private void validate( final Assembly assembly )
        throws InvalidAssemblerConfigurationException
    {
        if ( assembly.getId() == null || assembly.getId().trim().length() < 1 )
        {
            throw new InvalidAssemblerConfigurationException( "Assembly ID must be present and non-empty." );
        }
    }

    // CHECKSTYLE_OFF: LineLength
    private List<ContainerDescriptorHandler> selectContainerDescriptorHandlers(
        List<ContainerDescriptorHandlerConfig> requestedContainerDescriptorHandlers,
        final AssemblerConfigurationSource configSource )
        throws InvalidAssemblerConfigurationException
    // CHECKSTYLE_ON: LineLength
    {
        getLogger().debug( "All known ContainerDescriptorHandler components: " + ( containerDescriptorHandlers == null
            ? "none; map is null."
            : "" + containerDescriptorHandlers.keySet() ) );

        if ( requestedContainerDescriptorHandlers == null )
        {
            requestedContainerDescriptorHandlers = new ArrayList<>();
        }

        final List<ContainerDescriptorHandler> handlers = new ArrayList<>();
        final List<String> hints = new ArrayList<>();

        if ( !requestedContainerDescriptorHandlers.isEmpty() )
        {
            for ( final ContainerDescriptorHandlerConfig config : requestedContainerDescriptorHandlers )
            {
                final String hint = config.getHandlerName();
                final ContainerDescriptorHandler handler = containerDescriptorHandlers.get( hint );

                if ( handler == null )
                {
                    throw new InvalidAssemblerConfigurationException(
                        "Cannot find ContainerDescriptorHandler with hint: " + hint );
                }

                getLogger().debug(
                    "Found container descriptor handler with hint: " + hint + " (component: " + handler + ")" );

                if ( config.getConfiguration() != null )
                {
                    getLogger().debug( "Configuring handler with:\n\n" + config.getConfiguration() + "\n\n" );

                    configureContainerDescriptorHandler( handler, (Xpp3Dom) config.getConfiguration(), configSource );
                }

                handlers.add( handler );
                hints.add( hint );
            }
        }

        if ( !hints.contains( "plexus" ) )
        {
            handlers.add( new ComponentsXmlArchiverFileFilter() );
        }

        return handlers;
    }

    /**
     * Creates the necessary archiver to build the distribution file.
     *
     * @param format                Archive format
     * @param includeBaseDir        the base directory for include.
     * @param finalName             The final name.
     * @param configSource          {@link AssemblerConfigurationSource}
     * @param containerHandlers     The list of {@link ContainerDescriptorHandler}
     * @param recompressZippedFiles recompress zipped files.
     * @param mergeManifestMode     how to handle already existing Manifest files
     * @return archiver Archiver generated
     * @throws org.codehaus.plexus.archiver.ArchiverException
     * @throws org.codehaus.plexus.archiver.manager.NoSuchArchiverException
     */
    protected Archiver createArchiver( final String format, final boolean includeBaseDir, final String finalName,
                                       final AssemblerConfigurationSource configSource,
                                       final List<ContainerDescriptorHandler> containerHandlers,
                                       boolean recompressZippedFiles, String mergeManifestMode )
        throws NoSuchArchiverException
    {
        Archiver archiver;
        if ( "txz".equals( format ) || "tgz".equals( format ) || "tbz2".equals( format ) || format.startsWith( "tar" ) )
        {
            archiver = createTarArchiver( format, TarLongFileMode.valueOf( configSource.getTarLongFileMode() ) );
        }
        else if ( "war".equals( format ) )
        {
            archiver = createWarArchiver();
        }
        else
        {
            archiver = archiverManager.getArchiver( format );
        }

        if ( archiver instanceof AbstractZipArchiver )
        {
            ( (AbstractZipArchiver) archiver ).setRecompressAddedZips( recompressZippedFiles );
        }

        final List<FileSelector> extraSelectors = new ArrayList<>();
        final List<ArchiveFinalizer> extraFinalizers = new ArrayList<>();
        if ( archiver instanceof JarArchiver )
        {
            if ( mergeManifestMode != null )
            {
                ( (JarArchiver) archiver ).setFilesetmanifest(
                    JarArchiver.FilesetManifestConfig.valueOf( mergeManifestMode ) );
            }

            extraSelectors.add( new JarSecurityFileSelector() );

            extraFinalizers.add(
                new ManifestCreationFinalizer( configSource.getMavenSession(), configSource.getProject(),
                                               configSource.getJarArchiveConfiguration() ) );

        }

        if ( configSource.getArchiverConfig() != null )
        {
            configureArchiver( archiver, configSource );
        }

        String prefix = "";
        if ( includeBaseDir )
        {
            prefix = finalName;
        }

        archiver = new AssemblyProxyArchiver( prefix, archiver, containerHandlers, extraSelectors, extraFinalizers,
                                              configSource.getWorkingDirectory(), getLogger() );
        if ( configSource.isDryRun() )
        {
            archiver = new DryRunArchiver( archiver, getLogger() );
        }

        archiver.setUseJvmChmod( configSource.isUpdateOnly() );
        archiver.setIgnorePermissions( configSource.isIgnorePermissions() );
        archiver.setForced( !configSource.isUpdateOnly() );

        return archiver;
    }

    private void configureContainerDescriptorHandler( final ContainerDescriptorHandler handler, final Xpp3Dom config,
                                                      final AssemblerConfigurationSource configSource )
        throws InvalidAssemblerConfigurationException
    {
        getLogger().debug( "Configuring handler: '" + handler.getClass().getName() + "' -->" );

        try
        {
            configureComponent( handler, config, configSource );
        }
        catch ( final ComponentConfigurationException e )
        {
            throw new InvalidAssemblerConfigurationException(
                "Failed to configure handler: " + handler.getClass().getName(), e );
        }
        catch ( final ComponentLookupException e )
        {
            throw new InvalidAssemblerConfigurationException(
                "Failed to lookup configurator for setup of handler: " + handler.getClass().getName(), e );
        }

        getLogger().debug( "-- end configuration --" );
    }

    private void configureArchiver( final Archiver archiver, final AssemblerConfigurationSource configSource )
    {
        Xpp3Dom config;
        try
        {
            config = Xpp3DomBuilder.build( new StringReader( configSource.getArchiverConfig() ) );
        }
        catch ( final XmlPullParserException | IOException e )
        {
            throw new ArchiverException( "Failed to parse archiver configuration for: " + archiver.getClass().getName(),
                                         e );
        }

        getLogger().debug( "Configuring archiver: '" + archiver.getClass().getName() + "' -->" );

        try
        {
            configureComponent( archiver, config, configSource );
        }
        catch ( final ComponentConfigurationException e )
        {
            throw new ArchiverException( "Failed to configure archiver: " + archiver.getClass().getName(), e );
        }
        catch ( final ComponentLookupException e )
        {
            throw new ArchiverException(
                "Failed to lookup configurator for setup of archiver: " + archiver.getClass().getName(), e );
        }

        getLogger().debug( "-- end configuration --" );
    }

    private void configureComponent( final Object component, final Xpp3Dom config,
                                     final AssemblerConfigurationSource configSource )
        throws ComponentLookupException, ComponentConfigurationException
    {
        final ComponentConfigurator configurator = container.lookup( ComponentConfigurator.class, "basic" );

        final ConfigurationListener listener = new DebugConfigurationListener( getLogger() );

        final ExpressionEvaluator expressionEvaluator = new AssemblyExpressionEvaluator( configSource );

        final XmlPlexusConfiguration configuration = new XmlPlexusConfiguration( config );

        final Object[] containerRealm = getContainerRealm();

        /*
         * NOTE: The signature of configureComponent() has changed in Maven 3.x, the reflection prevents a linkage error
         * and makes the code work with both Maven 2 and 3.
         */
        try
        {
            final Method configureComponent =
                ComponentConfigurator.class.getMethod( "configureComponent", Object.class, PlexusConfiguration.class,
                                                       ExpressionEvaluator.class, (Class<?>) containerRealm[1],
                                                       ConfigurationListener.class );

            configureComponent.invoke( configurator, component, configuration, expressionEvaluator, containerRealm[0],
                                       listener );
        }
        catch ( final NoSuchMethodException | IllegalAccessException e )
        {
            throw new RuntimeException( e );
        }
        catch ( final InvocationTargetException e )
        {
            if ( e.getCause() instanceof ComponentConfigurationException )
            {
                throw (ComponentConfigurationException) e.getCause();
            }
            throw new RuntimeException( e.getCause() );
        }
    }

    private Object[] getContainerRealm()
    {
        /*
         * NOTE: The return type of getContainerRealm() has changed in Maven 3.x, the reflection prevents a linkage
         * error and makes the code work with both Maven 2 and 3.
         */
        try
        {
            final Method getContainerRealm = container.getClass().getMethod( "getContainerRealm" );
            return new Object[]{ getContainerRealm.invoke( container ), getContainerRealm.getReturnType() };
        }
        catch ( final NoSuchMethodException | IllegalAccessException e )
        {
            throw new RuntimeException( e );
        }
        catch ( final InvocationTargetException e )
        {
            throw new RuntimeException( e.getCause() );
        }
    }

    protected Archiver createWarArchiver()
        throws NoSuchArchiverException
    {
        final WarArchiver warArchiver = (WarArchiver) archiverManager.getArchiver( "war" );
        warArchiver.setIgnoreWebxml( false ); // See MNG-1274

        return warArchiver;
    }

    protected Archiver createTarArchiver( final String format, final TarLongFileMode tarLongFileMode )
        throws NoSuchArchiverException
    {
        final TarArchiver tarArchiver = (TarArchiver) archiverManager.getArchiver( "tar" );
        final int index = format.indexOf( '.' );
        if ( index >= 0 )
        {
            TarArchiver.TarCompressionMethod tarCompressionMethod;
            // TODO: this should accept gz and bz2 as well so we can skip
            // TODO: over the switch
            final String compression = format.substring( index + 1 );
            if ( "gz".equals( compression ) )
            {
                tarCompressionMethod = TarArchiver.TarCompressionMethod.gzip;
            }
            else if ( "bz2".equals( compression ) )
            {
                tarCompressionMethod = TarArchiver.TarCompressionMethod.bzip2;
            }
            else if ( "xz".equals( compression ) )
            {
                tarCompressionMethod = TarArchiver.TarCompressionMethod.xz;
            }
            else if ( "snappy".equals( compression ) )
            {
                tarCompressionMethod = TarArchiver.TarCompressionMethod.snappy;
            }
            else
            {
                // TODO: better handling
                throw new IllegalArgumentException( "Unknown compression format: " + compression );
            }
            tarArchiver.setCompression( tarCompressionMethod );
        }
        else if ( "tgz".equals( format ) )
        {
            tarArchiver.setCompression( TarArchiver.TarCompressionMethod.gzip );
        }
        else if ( "tbz2".equals( format ) )
        {
            tarArchiver.setCompression( TarArchiver.TarCompressionMethod.bzip2 );
        }
        else if ( "txz".equals( format ) )
        {
            tarArchiver.setCompression( TarArchiver.TarCompressionMethod.xz );
        }

        tarArchiver.setLongfile( tarLongFileMode );

        return tarArchiver;
    }

    @Override
    public void contextualize( final Context context )
        throws ContextException
    {
        container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
    }

    protected void setContainer( final PlexusContainer container )
    {
        this.container = container;
    }

}
