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

/*
 * 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.assembly.filter.ContainerDescriptorHandler;
import org.codehaus.plexus.archiver.ArchiveFinalizer;
import org.codehaus.plexus.archiver.ArchivedFileSet;
import org.codehaus.plexus.archiver.Archiver;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.FileSet;
import org.codehaus.plexus.archiver.FinalizerEnabled;
import org.codehaus.plexus.archiver.ResourceIterator;
import org.codehaus.plexus.archiver.util.DefaultArchivedFileSet;
import org.codehaus.plexus.archiver.util.DefaultFileSet;
import org.codehaus.plexus.components.io.fileselectors.FileInfo;
import org.codehaus.plexus.components.io.fileselectors.FileSelector;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;
import org.codehaus.plexus.components.io.resources.PlexusIoResourceCollection;
import org.codehaus.plexus.logging.Logger;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Delegating archiver implementation that supports:
 * <ul>
 * <li>dry-running (where the delegate archiver is never actually called)</li>
 * <li>prefixing (where all paths have a set global prefix prepended before addition)</li>
 * <li>duplication checks on archive additions (for archive-file path + prefix)</li>
 * </ul>
 * 
 * @author jdcasey
 * @version $Id$
 */
public class AssemblyProxyArchiver
    implements Archiver
{

    private final Archiver delegate;

    private String rootPrefix;

    private FileSelector[] selectors;

    private final ThreadLocal<Boolean> inPublicApi = new ThreadLocal<Boolean>();

    private final Logger logger;

    private final boolean dryRun;

    private boolean forced;

    private final Set<String> seenPaths = new HashSet<String>();

    private final String assemblyWorkPath;

    /**
     * @since 2.2
     */
    private boolean useJvmChmod;

    public AssemblyProxyArchiver( final String rootPrefix, final Archiver delegate,
                                  final List<ContainerDescriptorHandler> containerDescriptorHandlers,
                                  final List<FileSelector> extraSelectors,
                                  final List<ArchiveFinalizer> extraFinalizers, final File assemblyWorkDir,
                                  final Logger logger, final boolean dryRun )
    {
        this.rootPrefix = rootPrefix;
        this.delegate = delegate;

        assemblyWorkPath = assemblyWorkDir.getAbsolutePath()
                                          .replace( '\\', '/' );

        this.logger = logger;
        this.dryRun = dryRun;

        if ( !"".equals( rootPrefix ) && !rootPrefix.endsWith( "/" ) )
        {
            this.rootPrefix += "/";
        }

        final List<FileSelector> selectors = new ArrayList<FileSelector>();

        final boolean isFinalizerEnabled = ( delegate instanceof FinalizerEnabled );

        if ( containerDescriptorHandlers != null )
        {
            for ( final ContainerDescriptorHandler handler : containerDescriptorHandlers )
            {
                selectors.add( handler );

                if ( isFinalizerEnabled )
                {
                    ( (FinalizerEnabled) delegate ).addArchiveFinalizer( handler );
                }
            }
        }

        if ( extraSelectors != null )
        {
            for ( final FileSelector selector : extraSelectors )
            {
                selectors.add( selector );
            }
        }

        if ( ( extraFinalizers != null ) && isFinalizerEnabled )
        {
            for ( ArchiveFinalizer extraFinalizer : extraFinalizers )
            {
                ( (FinalizerEnabled) delegate ).addArchiveFinalizer( extraFinalizer );
            }
        }

        if ( !selectors.isEmpty() )
        {
            this.selectors = selectors.toArray( new FileSelector[selectors.size()] );
        }
    }

    public void addArchivedFileSet( final File archiveFile, final String prefix, final String[] includes,
                                    final String[] excludes )
        throws ArchiverException
    {
        final String archiveKey = getArchiveKey( archiveFile, prefix );
        if ( seenPaths.contains( archiveKey ) )
        {
            warn( "Archive: " + archiveFile + " has already been added. Skipping." );
            return;
        }

        inPublicApi.set( Boolean.TRUE );
        try
        {
            final DefaultArchivedFileSet fs = new DefaultArchivedFileSet();

            fs.setArchive( archiveFile );
            fs.setIncludes( includes );
            fs.setExcludes( excludes );
            fs.setPrefix( rootPrefix + prefix );
            fs.setFileSelectors( selectors );

            debug( "Adding archived file-set in: " + archiveFile + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                delegate.addArchivedFileSet( fs );
                seenPaths.add( archiveKey );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    private String getArchiveKey( final File archiveFile, final String prefix )
    {
        return archiveFile.getAbsolutePath() + ":" + prefix;
    }

    private void debug( final String message )
    {
        if ( ( logger != null ) && logger.isDebugEnabled() )
        {
            logger.debug( message );
        }
    }

    private void warn( final String message )
    {
        if ( ( logger != null ) && logger.isWarnEnabled() )
        {
            logger.warn( message );
        }
    }

    public void addArchivedFileSet( final File archiveFile, final String prefix )
        throws ArchiverException
    {
        final String archiveKey = getArchiveKey( archiveFile, prefix );
        if ( seenPaths.contains( archiveKey ) )
        {
            warn( "Archive: " + archiveFile + " has already been added. Skipping." );
            return;
        }

        inPublicApi.set( Boolean.TRUE );
        try
        {
            final DefaultArchivedFileSet fs = new DefaultArchivedFileSet();

            fs.setArchive( archiveFile );
            fs.setPrefix( rootPrefix + prefix );
            fs.setFileSelectors( selectors );

            debug( "Adding archived file-set in: " + archiveFile + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                delegate.addArchivedFileSet( fs );
                seenPaths.add( archiveKey );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addArchivedFileSet( final File archiveFile, final String[] includes, final String[] excludes )
        throws ArchiverException
    {
        final String archiveKey = getArchiveKey( archiveFile, "" );
        if ( seenPaths.contains( archiveKey ) )
        {
            warn( "Archive: " + archiveFile + " has already been added. Skipping." );
            return;
        }

        inPublicApi.set( Boolean.TRUE );
        try
        {
            final DefaultArchivedFileSet fs = new DefaultArchivedFileSet();

            fs.setArchive( archiveFile );
            fs.setIncludes( includes );
            fs.setExcludes( excludes );
            fs.setPrefix( rootPrefix );
            fs.setFileSelectors( selectors );

            debug( "Adding archived file-set in: " + archiveFile + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                delegate.addArchivedFileSet( fs );
                seenPaths.add( archiveKey );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addArchivedFileSet( final File archiveFile )
        throws ArchiverException
    {
        final String archiveKey = getArchiveKey( archiveFile, "" );
        if ( seenPaths.contains( archiveKey ) )
        {
            warn( "Archive: " + archiveFile + " has already been added. Skipping." );
            return;
        }

        inPublicApi.set( Boolean.TRUE );
        try
        {
            final DefaultArchivedFileSet fs = new DefaultArchivedFileSet();

            fs.setArchive( archiveFile );
            fs.setPrefix( rootPrefix );
            fs.setFileSelectors( selectors );

            debug( "Adding archived file-set in: " + archiveFile + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                delegate.addArchivedFileSet( fs );
                seenPaths.add( archiveKey );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addDirectory( final File directory, final String prefix, final String[] includes,
                              final String[] excludes )
        throws ArchiverException
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            final DefaultFileSet fs = new DefaultFileSet();

            fs.setDirectory( directory );
            fs.setIncludes( includes );
            fs.setExcludes( excludes );
            fs.setPrefix( rootPrefix + prefix );
            fs.setFileSelectors( selectors );

            debug( "Adding directory file-set in: " + directory + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                doAddFileSet( fs );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addDirectory( final File directory, final String prefix )
        throws ArchiverException
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            final DefaultFileSet fs = new DefaultFileSet();

            fs.setDirectory( directory );
            fs.setPrefix( rootPrefix + prefix );
            fs.setFileSelectors( selectors );

            debug( "Adding directory file-set in: " + directory + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                doAddFileSet( fs );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addDirectory( final File directory, final String[] includes, final String[] excludes )
        throws ArchiverException
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            final DefaultFileSet fs = new DefaultFileSet();

            fs.setDirectory( directory );
            fs.setIncludes( includes );
            fs.setExcludes( excludes );
            fs.setPrefix( rootPrefix );
            fs.setFileSelectors( selectors );

            debug( "Adding directory file-set in: " + directory + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                doAddFileSet( fs );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addDirectory( final File directory )
        throws ArchiverException
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            final DefaultFileSet fs = new DefaultFileSet();

            fs.setDirectory( directory );
            fs.setPrefix( rootPrefix );
            fs.setFileSelectors( selectors );

            debug( "Adding directory file-set in: " + directory + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                doAddFileSet( fs );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addFile( final File inputFile, final String destFileName, final int permissions )
        throws ArchiverException
    {
        if ( acceptFile( inputFile ) )
        {
            inPublicApi.set( Boolean.TRUE );
            try
            {
                debug( "Adding file: " + inputFile + " to archive location: " + rootPrefix + destFileName );

                if ( dryRun )
                {
                    debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
                }
                else
                {
                    delegate.addFile( inputFile, rootPrefix + destFileName, permissions );
                }
            }
            finally
            {
                inPublicApi.set( null );
            }
        }
    }

    public void addFile( final File inputFile, final String destFileName )
        throws ArchiverException
    {
        if ( acceptFile( inputFile ) )
        {
            inPublicApi.set( Boolean.TRUE );
            try
            {
                debug( "Adding file: " + inputFile + " to archive location: " + rootPrefix + destFileName );

                if ( dryRun )
                {
                    debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
                }
                else
                {
                    delegate.addFile( inputFile, rootPrefix + destFileName );
                }
            }
            finally
            {
                inPublicApi.set( null );
            }
        }
    }

    public void createArchive()
        throws ArchiverException, IOException
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                delegate.setForced( forced );
                delegate.createArchive();
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public int getDefaultDirectoryMode()
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            return delegate.getDefaultDirectoryMode();
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public int getDefaultFileMode()
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            return delegate.getDefaultFileMode();
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public File getDestFile()
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            return delegate.getDestFile();
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    @SuppressWarnings( { "rawtypes", "deprecation" } )
    public Map getFiles()
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            return delegate.getFiles();
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public boolean getIncludeEmptyDirs()
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            return delegate.getIncludeEmptyDirs();
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public boolean isForced()
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            return delegate.isForced();
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public boolean isSupportingForced()
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            return delegate.isSupportingForced();
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void setDefaultDirectoryMode( final int mode )
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.setDefaultDirectoryMode( mode );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void setDefaultFileMode( final int mode )
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.setDefaultFileMode( mode );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void setDestFile( final File destFile )
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.setDestFile( destFile );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void setForced( final boolean forced )
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            this.forced = forced;
            delegate.setForced( forced );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void setIncludeEmptyDirs( final boolean includeEmptyDirs )
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.setIncludeEmptyDirs( includeEmptyDirs );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void setDotFileDirectory( final File dotFileDirectory )
    {
        throw new UnsupportedOperationException( "Undocumented feature of plexus-archiver; this is not yet supported." );
    }

    public void addArchivedFileSet( final ArchivedFileSet fileSet )
        throws ArchiverException
    {
        final String archiveKey = getArchiveKey( fileSet.getArchive(), "" );
        if ( seenPaths.contains( archiveKey ) )
        {
            warn( "Archive: " + fileSet.getArchive() + " has already been added. Skipping." );
            return;
        }

        inPublicApi.set( Boolean.TRUE );
        try
        {
            final PrefixedArchivedFileSet fs = new PrefixedArchivedFileSet( fileSet, rootPrefix, selectors );

            debug( "Adding archived file-set in: " + fileSet.getArchive() + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                delegate.addArchivedFileSet( fs );
                seenPaths.add( archiveKey );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addFileSet( final FileSet fileSet )
        throws ArchiverException
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            final PrefixedFileSet fs = new PrefixedFileSet( fileSet, rootPrefix, selectors );

            debug( "Adding file-set in: " + fileSet.getDirectory() + " to archive location: " + fs.getPrefix() );

            if ( dryRun )
            {
                debug( "DRY RUN: Skipping delegated call to: " + getMethodName() );
            }
            else
            {
                doAddFileSet( fs );
            }
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    private void doAddFileSet( final FileSet fs )
        throws ArchiverException
    {
        final String fsPath = fs.getDirectory()
                                .getAbsolutePath()
                                .replace( '\\', '/' );

        if ( fsPath.equals( assemblyWorkPath ) )
        {
            logger.debug( "SKIPPING fileset with source directory matching assembly working-directory: " + fsPath );
        }
        else if ( assemblyWorkPath.startsWith( fsPath ) )
        {
            final List<String> newEx = new ArrayList<String>();
            if ( fs.getExcludes() != null )
            {
                newEx.addAll( Arrays.asList( fs.getExcludes() ) );
            }

            final String workDirExclude = assemblyWorkPath.substring( fsPath.length() + 1 );

            logger.debug( "Adding exclude for assembly working-directory: " + workDirExclude
                            + "\nFile-Set source directory: " + fsPath );

            newEx.add( workDirExclude );

            final List<String> newIn = new ArrayList<String>();
            if ( fs.getIncludes() != null )
            {
                for ( final String include : fs.getIncludes() )
                {
                    if ( !include.startsWith( workDirExclude ) )
                    {
                        newIn.add( include );
                    }
                }
            }

            final DefaultFileSet dfs = new DefaultFileSet();

            dfs.setCaseSensitive( fs.isCaseSensitive() );
            dfs.setDirectory( fs.getDirectory() );
            dfs.setExcludes( newEx.toArray( new String[newEx.size()] ) );
            dfs.setFileSelectors( fs.getFileSelectors() );
            dfs.setIncludes( newIn.toArray( new String[newIn.size()] ) );
            dfs.setIncludingEmptyDirectories( fs.isIncludingEmptyDirectories() );
            dfs.setPrefix( fs.getPrefix() );
            dfs.setUsingDefaultExcludes( fs.isUsingDefaultExcludes() );

            delegate.addFileSet( dfs );
        }
        else
        {
            delegate.addFileSet( fs );
        }
    }

    private String getMethodName()
    {
        final NullPointerException npe = new NullPointerException();
        final StackTraceElement[] trace = npe.getStackTrace();

        final StackTraceElement methodElement = trace[1];

        return methodElement.getMethodName() + " (archiver line: " + methodElement.getLineNumber() + ")";
    }

    private boolean acceptFile( final File inputFile )
        throws ArchiverException
    {
        if ( Boolean.TRUE != inPublicApi.get() )
        {
            if ( selectors != null )
            {
                final FileInfo fileInfo = new DefaultFileInfo( inputFile );

                for ( final FileSelector selector : selectors )
                {
                    try
                    {
                        if ( !selector.isSelected( fileInfo ) )
                        {
                            return false;
                        }
                    }
                    catch ( final IOException e )
                    {
                        throw new ArchiverException(
                            "Error processing file: " + inputFile + " using selector: " + selector, e );
                    }
                }
            }
        }

        return true;
    }

    private static final class DefaultFileInfo
        implements FileInfo
    {

        private final File inputFile;

        DefaultFileInfo( final File inputFile )
        {
            this.inputFile = inputFile;
        }

        public InputStream getContents()
            throws IOException
        {
            return new FileInputStream( inputFile );
        }

        public String getName()
        {
            return inputFile.getName();
        }

        public boolean isDirectory()
        {
            return inputFile.isDirectory();
        }

        public boolean isFile()
        {
            return inputFile.isFile();
        }

    }

    public void addResource( final PlexusIoResource resource, final String destFileName, final int permissions )
        throws ArchiverException
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.addResource( resource, destFileName, permissions );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void addResources( final PlexusIoResourceCollection resources )
        throws ArchiverException
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.addResources( resources );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public ResourceIterator getResources()
        throws ArchiverException
    {
        return delegate.getResources();
    }

    public String getDuplicateBehavior()
    {
        return delegate.getDuplicateBehavior();
    }

    public void setDuplicateBehavior( final String duplicate )
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.setDuplicateBehavior( duplicate );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public int getDirectoryMode()
    {
        return delegate.getDirectoryMode();
    }

    public int getFileMode()
    {
        return delegate.getFileMode();
    }

    public int getOverrideDirectoryMode()
    {
        return delegate.getOverrideDirectoryMode();
    }

    public int getOverrideFileMode()
    {
        return delegate.getOverrideFileMode();
    }

    public void setDirectoryMode( final int mode )
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.setDirectoryMode( mode );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public void setFileMode( final int mode )
    {
        inPublicApi.set( Boolean.TRUE );
        try
        {
            delegate.setFileMode( mode );
        }
        finally
        {
            inPublicApi.set( null );
        }
    }

    public boolean isUseJvmChmod()
    {
        return useJvmChmod;
    }

    public void setUseJvmChmod( final boolean useJvmChmod )
    {
        this.useJvmChmod = useJvmChmod;
    }

    public boolean isIgnorePermissions()
    {
        return delegate.isIgnorePermissions();
    }

    public void setIgnorePermissions( final boolean ignorePermissions )
    {
        delegate.setIgnorePermissions( ignorePermissions );
    }

}
