/******************************************************************************
 * Copyright (c) 2010 Oracle
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Konstantin Komissarchik - initial implementation and ongoing maintenance
 ******************************************************************************/

package org.eclipse.jst.common.project.facet.core.libprov.user.internal;

import static org.eclipse.jdt.core.IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME;
import static org.eclipse.jst.common.project.facet.core.internal.FacetedProjectFrameworkJavaPlugin.PLUGIN_ID;
import static org.eclipse.wst.common.project.facet.core.util.internal.ZipUtil.unzip;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IAccessRule;
import org.eclipse.jdt.core.IClasspathAttribute;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.JavaModelManager;
import org.eclipse.jdt.internal.core.UserLibraryManager;
import org.eclipse.osgi.util.NLS;

/**
 * @author <a href="mailto:konstantin.komissarchik@oracle.com">Konstantin Komissarchik</a>
 */

@SuppressWarnings( "restriction" )

public final class DownloadableLibrary
{
    private String name;
    private String downloadProvider;
    private String url;
    private String licenseUrl;
    
    private Map<IPath,DownloadableLibraryComponentAttributes> componentAttributesMap
        = new HashMap<IPath,DownloadableLibraryComponentAttributes>();
    
    private final List<String> includePatterns = new ArrayList<String>();
    private final List<String> includePatternsReadOnly = Collections.unmodifiableList( this.includePatterns );
    private final List<String> excludePatterns = new ArrayList<String>();
    private final List<String> excludePatternsReadOnly = Collections.unmodifiableList( this.excludePatterns );
    
    public String getName()
    {
        return this.name;
    }
    
    public void setName( final String name )
    {
        this.name = name;
    }
    
    public String getDownloadProvider()
    {
        return this.downloadProvider;
    }
    
    public void setDownloadProvider( final String downloadProvider )
    {
        this.downloadProvider = downloadProvider;
    }
    
    public String getUrl()
    {
        return this.url;
    }
    
    public void setUrl( final String url )
    {
        this.url = url;
    }
    
    public String getLicenseUrl()
    {
        return this.licenseUrl;
    }
    
    public void setLicenseUrl( final String licenseUrl )
    {
        this.licenseUrl = licenseUrl;
    }
    
    public DownloadableLibraryComponentAttributes getComponentAttributes( final IPath path )
    {
        return getComponentAttributes( path, false );
    }
    
    public DownloadableLibraryComponentAttributes getComponentAttributes( final IPath path,
                                                                          final boolean createIfNecessary )
    {
        DownloadableLibraryComponentAttributes attachment = this.componentAttributesMap.get( path );
        
        if( attachment == null && createIfNecessary )
        {
            attachment = new DownloadableLibraryComponentAttributes( path.toPortableString() );
            this.componentAttributesMap.put( path, attachment );
        }
        
        return attachment;
    }
    
    public Collection<String> getIncludePatterns()
    {
        return this.includePatternsReadOnly;
    }
    
    public void addIncludePattern( final String includePattern )
    {
        if( includePattern == null )
        {
            return;
        }
        
        for( String segment : includePattern.split( "," ) ) //$NON-NLS-1$
        {
            segment = segment.trim();
            
            if( segment.length() > 0 )
            {
                this.includePatterns.add( segment );
            }
        }
    }
        
    public Collection<String> getExcludePatterns()
    {
        return this.excludePatternsReadOnly;
    }
    
    public void addExcludePattern( final String excludePattern )
    {
        if( excludePattern == null )
        {
            return;
        }
        
        for( String segment : excludePattern.split( "," ) ) //$NON-NLS-1$
        {
            segment = segment.trim();
            
            if( segment.length() > 0 )
            {
                this.excludePatterns.add( segment );
            }
        }
    }
        
    public void download( final File destFolder,
                          final String localLibraryName,
                          final IProgressMonitor monitor )
    
        throws CoreException, InterruptedException
        
    {
        try 
        {
            // Create the directory where the downloaded archive will be written to
            // and where the exploded library will reside.
            
            destFolder.mkdirs();
            
            // Make sure that destination folder is empty and clear it out if necessary.
            
            for( File f : destFolder.listFiles() )
            {
                delete( f );
            }

            // Define the temporary download file.
            
            final File destFile = new File( destFolder, "download.zip" ); //$NON-NLS-1$
            
            // Perform the download.
                
            download( new URL( this.url ), destFile, monitor );
            
            // Unzip the downloaded file.

            unzip( destFile, destFolder, monitor );
            
            // Delete the original downloaded file.
            
            destFile.delete();
            
            // Configure the user library.
            
            final List<IClasspathEntry> entries = new ArrayList<IClasspathEntry>();
            final IPath destFolderPath = new Path( destFolder.getPath() );
            
            for( File jarFile : findAllJarFiles( destFolder ) )
            {
                final IPath jarPath = new Path( jarFile.getPath() );
                final IPath relativeJarPath = jarPath.makeRelativeTo( destFolderPath );
                
                if( ! shouldInclude( relativeJarPath ) )
                {
                    continue;
                }
                
                IPath sourceArchivePath = null;
                String javadocArchivePath = null;

                final DownloadableLibraryComponentAttributes attachment = getComponentAttributes( relativeJarPath );
                
                if( attachment != null )
                {
                    final String sourceArchivePathString = attachment.getSourceArchivePath();
                    
                    if( sourceArchivePathString != null )
                    {
                        sourceArchivePath = destFolderPath.append( sourceArchivePathString );
                    }
                    
                    javadocArchivePath = attachment.getJavadocArchivePath();
                    
                    if( javadocArchivePath != null )
                    {
                        final int separator = javadocArchivePath.indexOf( '!' );
                        final IPath pathInArchive;
                        
                        if( separator == -1 )
                        {
                            pathInArchive = null;
                        }
                        else
                        {
                            pathInArchive = new Path( javadocArchivePath.substring( separator + 1 ) );
                            javadocArchivePath = javadocArchivePath.substring( 0, separator );
                        }
                        
                        final IPath p = destFolderPath.append( javadocArchivePath );
                        
                        if( pathInArchive != null || p.toFile().isFile() )
                        {
                            javadocArchivePath = "jar:file:/" + p.toPortableString() + "!/"; //$NON-NLS-1$ //$NON-NLS-2$
                            
                            if( javadocArchivePath != null )
                            {
                                javadocArchivePath = javadocArchivePath + pathInArchive.toPortableString() + "/"; //$NON-NLS-1$
                            }
                        }
                        else
                        {
                            javadocArchivePath = "file:/" + p.toPortableString() + "/"; //$NON-NLS-1$ //$NON-NLS-2$
                        }
                    }
                }
                
                final IClasspathEntry cpe = newLibraryEntry( jarPath, sourceArchivePath, javadocArchivePath );
                entries.add( cpe );
            }
            
            final IClasspathEntry[] entriesArray 
                = entries.toArray( new IClasspathEntry[ entries.size() ] );
            
            final UserLibraryManager userLibraryManager = JavaModelManager.getUserLibraryManager();
            userLibraryManager.setUserLibrary( localLibraryName, entriesArray, false );
        }
        catch( IOException e )
        {
            final IStatus st = new Status( IStatus.ERROR, PLUGIN_ID, Resources.failedWhileDownloading, e );
            throw new CoreException( st );
        }
    }
    
    private void download( final URL url,
                           final File destFile,
                           final IProgressMonitor monitor )
    
        throws IOException, InterruptedException
        
    {
        monitor.setTaskName( Resources.progressConnecting );
        
        final URLConnection urlConnection = url.openConnection();
        final int size = urlConnection.getContentLength();
        
        final String totalSizeString;
        
        if( size == -1 )
        {
            totalSizeString = null;
            monitor.beginTask( Resources.progressTransferStarted, IProgressMonitor.UNKNOWN );
        }
        else
        {
            totalSizeString = formatByteCount( size );
            monitor.beginTask( Resources.progressTransferStarted, size );
        }
        
        InputStream in = null;
        FileOutputStream out = null;
        
        try
        {
            in = urlConnection.getInputStream();
            out = new FileOutputStream( destFile );
            
            final byte[] buffer = new byte[ 16 * 1024 ];
            
            int count = 0;
            int bytesTransfered = 0;
            
            while( ( count = in.read( buffer ) ) != -1 )
            {
                if( monitor.isCanceled() )
                {
                    throw new InterruptedException();
                }
                
                out.write( buffer, 0, count );
                bytesTransfered += count;
                
                monitor.worked( count );
                monitor.setTaskName( formatDownloadProgressMessage( bytesTransfered, totalSizeString ) );
            }
        }
        finally
        {
            if( in != null )
            {
                try
                {
                    in.close();
                }
                catch( IOException e ) {}
            }
            
            if( out != null )
            {
                try
                {
                    out.close();
                }
                catch( IOException e ) {}
            }
            
            monitor.done();
        }
    }
    
    private boolean shouldInclude( final IPath path )
    {
        if( ! this.includePatterns.isEmpty() )
        {
            boolean included = false;
            
            for( String pattern : this.includePatterns )
            {
                if( path.equals( new Path( pattern ) ) )
                {
                    included = true;
                    break;
                }
            }
            
            if( ! included )
            {
                return false;
            }
        }
        
        for( String pattern : this.excludePatterns )
        {
            if( path.equals( new Path( pattern ) ) )
            {
                return false;
            }
        }
        
        return true;
    }
    
    private String formatByteCount( final int byteCount )
    {
        if( byteCount < 1024 * 1024 )
        {
            return String.format( "%3.0f KB", ( (float) byteCount ) / 1024 ); //$NON-NLS-1$
        }
        else
        {
            return String.format( "%.1f MB" , ( (float) byteCount ) / ( 1024 * 1024 ) ); //$NON-NLS-1$
        }
    }
    
    private String formatDownloadProgressMessage( final int bytesTransfered,
                                                  final String totalSizeString )
    {
        final String bytesTransferedString = formatByteCount( bytesTransfered );
        
        if( totalSizeString != null )
        {
            return NLS.bind( Resources.progressTransferred, bytesTransferedString, totalSizeString );
        }
        else
        {
            return NLS.bind( Resources.progressTransferredNoTotalSize, bytesTransferedString );
        }
    }
    
    private static void delete( final File f )

        throws IOException
    
    {
        if( f.isDirectory() )
        {
            for( File child : f.listFiles() )
            {
                delete( child );
            }
        }
    
        if( ! f.delete() )
        {
            final String msg = NLS.bind( Resources.errorCouldNotDelete, f.getPath() );
            throw new IOException( msg );
        }
    }
    
    private static List<File> findAllJarFiles( final File directory )
    {
        final List<File> result = new ArrayList<File>();
        findAllJarFiles( directory, result );
        return result;
    }
    
    private static void findAllJarFiles( final File directory,
                                         final List<File> result )
    {
        for( File f : directory.listFiles() )
        {
            if( f.isDirectory() )
            {
                findAllJarFiles( f, result );
            }
            else
            {
                final String fname = f.getName().toLowerCase();
                
                if( fname.endsWith( ".jar" ) ) //$NON-NLS-1$
                {
                    result.add( f );
                }
            }
        }
    }
    
    private static IClasspathEntry newLibraryEntry( final IPath library,
                                                    final IPath src,
                                                    final String javadoc )
    {
        final IAccessRule[] access = {};
        
        final IClasspathAttribute[] attrs;
        
        if( javadoc == null )
        {
            attrs = new IClasspathAttribute[ 0 ];
        }
        else
        {
            attrs = new IClasspathAttribute[]
            { 
               JavaCore.newClasspathAttribute( JAVADOC_LOCATION_ATTRIBUTE_NAME, javadoc )
            };
        }
        
        return JavaCore.newLibraryEntry( library, src, null, access, attrs, false );
    }
    
    
    private static final class Resources
    
        extends NLS
        
    {
        public static String failedWhileDownloading;
        public static String progressConnecting;
        public static String progressTransferStarted;
        public static String progressTransferred;
        public static String progressTransferredNoTotalSize;
        public static String errorCouldNotDelete;
    
        static
        {
            initializeMessages( DownloadableLibrary.class.getName(), 
                                Resources.class );
        }
    }
    
}
