//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.maven.plugin;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.Manifest;

import org.codehaus.plexus.util.SelectorUtils;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.JarResource;



/**
 * SelectiveJarResource
 *
 * Selectively copies resources from a jar file based on includes/excludes.
 * 
 */
public class SelectiveJarResource extends JarResource
{  
    private static final Logger LOG = Log.getLogger(SelectiveJarResource.class);
    public static final List<String> DEFAULT_INCLUDES = Arrays.asList(new String[]{"**"});// No includes supplied, so set it to 'matches all'
    public static final List<String> DEFAULT_EXCLUDES = Collections.emptyList(); //No includes, set to no exclusions


    List<String> _includes = null;
    List<String> _excludes = null;
    boolean _caseSensitive = false;
    

    /**
     * @param url
     */
    public SelectiveJarResource(URL url)
    {
        super(url);
    }
  
    /**
     * @param url
     * @param useCaches
     */
    public SelectiveJarResource(URL url, boolean useCaches)
    {
        super(url, useCaches);
    }
    
    
    public void setCaseSensitive (boolean caseSensitive)
    {
        _caseSensitive = caseSensitive;
    }
    
    public void setIncludes (List<String> patterns)
    {
        _includes = patterns;
    }
    
    
    public void setExcludes (List<String> patterns)
    {
        _excludes = patterns;
    }
    
    
    protected boolean isIncluded (String name)
    {    
        for (String include:_includes)
        {
            if (SelectorUtils.matchPath(include, name, _caseSensitive))
            {
                return true;
            }
        }
        return false;
    }
    
    protected boolean isExcluded (String name)
    {
        for (String exclude:_excludes)
        {
            if (SelectorUtils.matchPath (exclude, name, _caseSensitive))
            {
                return true;
            }
        }
        return false;
    }
    
    
  

    /** 
     * @see org.eclipse.jetty.util.resource.JarResource#copyTo(java.io.File)
     */
    @Override
    public void copyTo(File directory) throws IOException
    {
        if (_includes == null)
            _includes = DEFAULT_INCLUDES;
        if (_excludes == null)
            _excludes = DEFAULT_EXCLUDES;
        
        //Copy contents of the jar file to the given directory, 
        //using the includes and excludes patterns to control which
        //parts of the jar file are copied
        if (!exists())
            return;
        
        String urlString = this.getURL().toExternalForm().trim();
        int endOfJarUrl = urlString.indexOf("!/");
        int startOfJarUrl = (endOfJarUrl >= 0?4:0);
        
        if (endOfJarUrl < 0)
            throw new IOException("Not a valid jar url: "+urlString);
        
        URL jarFileURL = new URL(urlString.substring(startOfJarUrl, endOfJarUrl));
     
        try (InputStream is = jarFileURL.openConnection().getInputStream();
                JarInputStream jin = new JarInputStream(is))
        {
            JarEntry entry;

            while((entry=jin.getNextJarEntry())!=null)
            {
                String entryName = entry.getName();

                LOG.debug("Looking at "+entryName);
                String dotCheck = entryName.replace('\\', '/');
                dotCheck = URIUtil.canonicalPath(dotCheck);
                if (dotCheck == null)
                {
                    LOG.info("Invalid entry: "+entryName);
                    continue;
                }

                File file=new File(directory,entryName);

                if (entry.isDirectory())
                {
                    if (isIncluded(entryName))
                    {
                        if (!isExcluded(entryName))
                        {
                            // Make directory
                            if (!file.exists())
                                file.mkdirs();
                        }
                        else
                            LOG.debug("{} dir is excluded", entryName);
                    }
                    else
                        LOG.debug("{} dir is NOT included", entryName);
                }
                else
                {
                    //entry is a file, is it included?
                    if (isIncluded(entryName))
                    {
                        if (!isExcluded(entryName))
                        {
                            // make directory (some jars don't list dirs)
                            File dir = new File(file.getParent());
                            if (!dir.exists())
                                dir.mkdirs();

                            // Make file
                            try (OutputStream fout = new FileOutputStream(file))
                            {
                                IO.copy(jin,fout);
                            }

                            // touch the file.
                            if (entry.getTime()>=0)
                                file.setLastModified(entry.getTime());
                        }
                        else
                            LOG.debug("{} file is excluded", entryName);
                    }
                    else
                        LOG.debug("{} file is NOT included", entryName);
                }
            }

            Manifest manifest = jin.getManifest();
            if (manifest != null)
            {
                if (isIncluded("META-INF") && !isExcluded("META-INF"))
                {
                    File metaInf = new File (directory, "META-INF");
                    metaInf.mkdir();
                    File f = new File(metaInf, "MANIFEST.MF");
                    try (OutputStream fout = new FileOutputStream(f))
                    {
                        manifest.write(fout);
                    }
                }
            }
        }
    }
    
}
