package org.apache.maven.shared.model.fileset.util;

/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed 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.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.maven.plugin.logging.Log;
import org.apache.maven.shared.model.fileset.FileSet;
import org.codehaus.plexus.util.DirectoryScanner;

/**
 * Provides operations for use with FileSet instances, such as retrieving the included/excluded
 * files, deleting all matching entries, etc.
 * 
 * @author jdcasey
 *
 */
public class FileSetManager
{
    
    private static final int DELETE_RETRY_SLEEP_MILLIS = 10;
    private static final String[] EMPTY_STRING_ARRAY = new String[0];
    
    private final boolean verbose;
    private final Log log;

    /**
     * Create a new manager instance with the supplied log instance and flag for whether to output
     * verbose messages.
     * 
     * @param log The mojo log instance
     * @param verbose Whether to output verbose messages
     */
    public FileSetManager( Log log, boolean verbose )
    {
        this.log = log;
        this.verbose = verbose;
    }
    
    /**
     * Create a new manager instance with the supplied log instance. Verbose flag is set to false.
     * 
     * @param log The mojo log instance
     */
    public FileSetManager( Log log )
    {
        this.log = log;
        this.verbose = false;
    }
    
    /**
     * Create a new manager instance with an empty log. Verbose flag is set to false.
     * 
     * @param log The mojo log instance
     */
    public FileSetManager()
    {
        this.log = null;
        this.verbose = false;
    }
    
    /**
     * Get all the filenames which have been included by the rules in this fileset.
     * @param fileSet The fileset defining rules for inclusion/exclusion, and base directory.
     * @return the array of matching filenames, relative to the basedir of the file-set.
     */
    public String[] getIncludedFiles( FileSet fileSet )
    {
        DirectoryScanner scanner = scan( fileSet );
        
        if ( scanner != null )
        {
            return scanner.getIncludedFiles();
        }        
        else
        {
            return EMPTY_STRING_ARRAY;
        }
    }

    /**
     * Get all the directory names which have been included by the rules in this fileset.
     * @param fileSet The fileset defining rules for inclusion/exclusion, and base directory.
     * @return the array of matching dirnames, relative to the basedir of the file-set.
     */
    public String[] getIncludedDirectories( FileSet fileSet )
    {
        DirectoryScanner scanner = scan( fileSet );
        
        if ( scanner != null )
        {
            return scanner.getIncludedDirectories();
        }        
        else
        {
            return EMPTY_STRING_ARRAY;
        }
    }

    /**
     * Get all the filenames which have been excluded by the rules in this fileset.
     * @param fileSet The fileset defining rules for inclusion/exclusion, and base directory.
     * @return the array of non-matching filenames, relative to the basedir of the file-set.
     */
    public String[] getExcludedFiles( FileSet fileSet )
    {
        DirectoryScanner scanner = scan( fileSet );
        
        if ( scanner != null )
        {
            return scanner.getExcludedFiles();
        }        
        else
        {
            return EMPTY_STRING_ARRAY;
        }
    }

    /**
     * Get all the directory names which have been excluded by the rules in this fileset.
     * @param fileSet The fileset defining rules for inclusion/exclusion, and base directory.
     * @return the array of non-matching dirnames, relative to the basedir of the file-set.
     */
    public String[] getExcludedDirectories( FileSet fileSet )
    {
        DirectoryScanner scanner = scan( fileSet );
        
        if ( scanner != null )
        {
            return scanner.getExcludedDirectories();
        }        
        else
        {
            return EMPTY_STRING_ARRAY;
        }
    }
    
    /**
     * Delete the matching files and directories for the given file-set definition.
     * @param fileSet The file-set matching rules, along with search base directory
     * @throws IOException If a matching file cannot be deleted
     */
    public void delete( FileSet fileSet ) throws IOException
    {
        Set deletablePaths = findDeletablePaths( fileSet );
        
        if ( log != null && log.isDebugEnabled() )
        {
            log.debug( "Found deletable paths: " + String.valueOf( deletablePaths ).replace( ',', '\n' ) );
        }        
        
        for ( Iterator it = deletablePaths.iterator(); it.hasNext(); )
        {
            String path = (String) it.next();
            
            File file = new File( fileSet.getDirectory(), path );
            
            if ( file.exists() )
            {
                if ( file.isDirectory() && ( fileSet.isFollowSymlinks() || !isSymlink( file ) ) )
                {
                    if ( verbose && log != null )
                    {
                        log.info( "Deleting directory: " + file );
                    }
                    
                    removeDir( file, fileSet.isFollowSymlinks() );
                }
                else
                {
                    if ( verbose && log != null )
                    {
                        log.info( "Deleting file: " + file );
                    }
                    
                    if ( !delete( file ) )
                    {
                        throw new IOException( "Failed to delete file: " + file + ". Reason is unknown." );
                    }
                }
            }            
        }
    }
    
    private boolean isSymlink( File file ) throws IOException
    {
        File parent = file.getParentFile();
        File canonicalFile = file.getCanonicalFile();
        
        if ( log != null && log.isDebugEnabled() )
        {
            log.debug( "Checking for symlink:\nParent file's canonical path: " + parent.getCanonicalPath()
                + "\nMy canonical path: " + canonicalFile.getPath() );
        }        
        return parent != null && ( !canonicalFile.getName().equals( file.getName() ) || !canonicalFile.getPath().startsWith( parent.getCanonicalPath() ) );
    }

    private Set findDeletablePaths( FileSet fileSet )
    {
        Set includes = findDeletableDirectories( fileSet );
        includes.addAll( findDeletableFiles( fileSet, includes ) );
        
        return includes;
    }

    private Set findDeletableDirectories( FileSet fileSet )
    {
        if ( verbose && log != null )
        {
            log.info( "Scanning for deletable directories." );
        }
        
        DirectoryScanner scanner = scan( fileSet );
        
        if ( scanner == null )
        {
            return Collections.EMPTY_SET;
        }
        
        String[] includedDirs = scanner.getIncludedDirectories();
        String[] excludedDirs = scanner.getExcludedDirectories();
        
        Set includes = new HashSet( Arrays.asList( includedDirs ) );
        List excludes = new ArrayList( Arrays.asList( excludedDirs ) );
        List linksForDeletion = new ArrayList();
        
        if ( !fileSet.isFollowSymlinks() )
        {
            if ( verbose && log != null )
            {
                log.info( "Adding symbolic link dirs which were previously excluded to the list being deleted." );
            }
            
            // we need to see which entries were excluded because they're symlinks...
            scanner.setFollowSymlinks( true );
            scanner.scan();
            
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "Originally marked for delete: " + includes );
                log.debug( "Marked for preserve (with followSymlinks == false): " + excludes );
            }
            
            List notSymlinks = Arrays.asList( scanner.getIncludedDirectories() );
            
            linksForDeletion.addAll( excludes );
            linksForDeletion.retainAll( notSymlinks );
            
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "Symlinks marked for deletion (originally mismarked): " + linksForDeletion );
            }
            
            excludes.removeAll( notSymlinks );
        }
        
        for ( int i = 0; i < excludedDirs.length; i++ )
        {
            String path = excludedDirs[i];
            
            File excluded = new File( path );
            
            String parentPath = excluded.getParent();
            
            while( parentPath != null )
            {
                if ( log != null && log.isDebugEnabled() )
                {
                    log.debug( "Verifying path: " + parentPath + " is not present; contains file which is excluded." );
                }
                
                boolean removed = includes.remove( parentPath );
                
                if ( removed && log != null && log.isDebugEnabled() )
                {
                    log.debug( "Path: " + parentPath + " was removed from delete list." );
                }
                
                parentPath = new File( parentPath ).getParent();
            }
        }
        
        includes.addAll( linksForDeletion );
        
        return includes;
    }

    private Set findDeletableFiles( FileSet fileSet, Set deletableDirectories )
    {
        if ( verbose && log != null )
        {
            log.info( "Re-scanning for deletable files." );
        }
        
        DirectoryScanner scanner = scan( fileSet );
        
        if ( scanner == null )
        {
            return deletableDirectories;
        }
        
        String[] includedFiles = scanner.getIncludedFiles();
        String[] excludedFiles = scanner.getExcludedFiles();
        
        Set includes = deletableDirectories;
        includes.addAll( Arrays.asList( includedFiles ) );
        List excludes = new ArrayList( Arrays.asList( excludedFiles ) );
        List linksForDeletion = new ArrayList();
        
        if ( !fileSet.isFollowSymlinks() )
        {
            if ( verbose && log != null )
            {
                log.info( "Adding symbolic link files which were previously excluded to the list being deleted." );
            }
            
            // we need to see which entries were excluded because they're symlinks...
            scanner.setFollowSymlinks( true );
            scanner.scan();
            
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "Originally marked for delete: " + includes );
                log.debug( "Marked for preserve (with followSymlinks == false): " + excludes );
            }
            
            List notSymlinks = Arrays.asList( scanner.getExcludedFiles() );
            
            linksForDeletion.addAll( excludes );
            linksForDeletion.retainAll( notSymlinks );
            
            if ( log != null && log.isDebugEnabled() )
            {
                log.debug( "Symlinks marked for deletion (originally mismarked): " + linksForDeletion );
            }
            
            excludes.removeAll( notSymlinks );
        }
        
        for ( int i = 0; i < excludedFiles.length; i++ )
        {
            String path = excludedFiles[i];
            
            File excluded = new File( path );
            
            String parentPath = excluded.getParent();
            
            while( parentPath != null )
            {
                if ( log != null && log.isDebugEnabled() )
                {
                    log.debug( "Verifying path: " + parentPath + " is not present; contains file which is excluded." );
                }
                
                boolean removed = includes.remove( parentPath );
                
                if ( removed && log != null && log.isDebugEnabled() )
                {
                    log.debug( "Path: " + parentPath + " was removed from delete list." );
                }
                
                parentPath = new File( parentPath ).getParent();
            }
        }
        
        includes.addAll( linksForDeletion );
        
//        for ( Iterator it = includes.iterator(); it.hasNext(); )
//        {
//            String path = (String) it.next();
//            
//            if ( includes.contains( new File( path ).getParent() ) )
//            {
//                it.remove();
//            }
//        }
        
        return includes;
    }

    /**
     * Delete a directory
     *
     * @param dir the directory to delete
     * @param followSymlinks whether to follow symbolic links, or simply delete the link
     */
    private void removeDir( File dir, boolean followSymlinks )
        throws IOException
    {
        String[] list = dir.list();
        if ( list == null )
        {
            list = new String[0];
        }
        for ( int i = 0; i < list.length; i++ )
        {
            String s = list[i];
            File f = new File( dir, s );
            if ( f.isDirectory() && ( followSymlinks || !isSymlink( f ) ) )
            {
                removeDir( f, followSymlinks );
            }
            else
            {
                if ( !delete( f ) )
                {
                    String message = "Unable to delete file " + f.getAbsolutePath();
// TODO:...
//                    if ( failOnError )
//                    {
                        throw new IOException( message );
//                    }
//                    else
//                    {
//                        getLog().info( message );
//                    }
                }
            }
        }

        if ( !delete( dir ) )
        {
            String message = "Unable to delete directory " + dir.getAbsolutePath();
// TODO:...
//            if ( failOnError )
//            {
                throw new IOException( message );
//            }
//            else
//            {
//                getLog().info( message );
//            }
        }
    }
    
    /**
     * Accommodate Windows bug encountered in both Sun and IBM JDKs.
     * Others possible. If the delete does not work, call System.gc(),
     * wait a little and try again.
     */
    private boolean delete( File f )
    {
        if ( !f.delete() )
        {
            if ( System.getProperty( "os.name" ).toLowerCase().indexOf( "windows" ) > -1 )
            {
                System.gc();
            }
            try
            {
                Thread.sleep( DELETE_RETRY_SLEEP_MILLIS );
                return f.delete();
            }
            catch ( InterruptedException ex )
            {
                return f.delete();
            }
        }
        
        return true;
    }

    private DirectoryScanner scan( FileSet fileSet )
    {
        File basedir = new File( fileSet.getDirectory() );
        if ( !basedir.exists() )
        {
            return null;
        }
        
        DirectoryScanner scanner = new DirectoryScanner();
        
        String[] includesArray = fileSet.getIncludesArray();
        String[] excludesArray = fileSet.getExcludesArray();
        
        if ( includesArray.length < 1 && excludesArray.length < 1 )
        {
            scanner.setIncludes( new String[]{ "**" } );
        }
        else
        {
            scanner.setIncludes( includesArray );
            scanner.setExcludes( excludesArray );
        }
        
        scanner.setBasedir( basedir );
        scanner.setFollowSymlinks( fileSet.isFollowSymlinks() );

        scanner.scan();
        
        return scanner;
    }

}
