//
//  ========================================================================
//  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.util.resource;

import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

/* ------------------------------------------------------------ */
class JarFileResource extends JarResource
{
    private static final Logger LOG = Log.getLogger(JarFileResource.class);
    private JarFile _jarFile;
    private File _file;
    private String[] _list;
    private JarEntry _entry;
    private boolean _directory;
    private String _jarUrl;
    private String _path;
    private boolean _exists;
    
    /* -------------------------------------------------------- */
    protected JarFileResource(URL url)
    {
        super(url);
    }
    
    /* ------------------------------------------------------------ */
    protected JarFileResource(URL url, boolean useCaches)
    {
        super(url, useCaches);
    }   

    /* ------------------------------------------------------------ */
    @Override
    public synchronized void close()
    {
        _exists=false;
        _list=null;
        _entry=null;
        _file=null;
        //if the jvm is not doing url caching, then the JarFiles will not be cached either,
        //and so they are safe to close
        if (!getUseCaches())
        {
            if ( _jarFile != null )
            {
                try
                {
                    if (LOG.isDebugEnabled())
                        LOG.debug("Closing JarFile "+_jarFile.getName());
                    _jarFile.close();
                }
                catch ( IOException ioe )
                {
                    LOG.ignore(ioe);
                }
            }
        }
        _jarFile=null;
        super.close();
    }
    
    /* ------------------------------------------------------------ */
    @Override
    protected synchronized boolean checkConnection()
    {
        try
        {
            super.checkConnection();
        }
        finally
        {
            if (_jarConnection==null)
            {
                _entry=null;
                _file=null;
                _jarFile=null;
                _list=null;
            }
        }
        return _jarFile!=null;
    }


    /* ------------------------------------------------------------ */
    @Override
    protected synchronized void newConnection()
        throws IOException
    {
        super.newConnection();
        
        _entry=null;
        _file=null;
        _jarFile=null;
        _list=null;
        
        int sep = _urlString.lastIndexOf("!/");
        _jarUrl=_urlString.substring(0,sep+2);
        _path=_urlString.substring(sep+2);
        if (_path.length()==0)
            _path=null;   
        _jarFile=_jarConnection.getJarFile();
        _file=new File(_jarFile.getName());
    }
    
    
    /* ------------------------------------------------------------ */
    /**
     * Returns true if the represented resource exists.
     */
    @Override

    public boolean exists()
    {
        if (_exists)
            return true;

        if (_urlString.endsWith("!/"))
        {
            String file_url=_urlString.substring(4,_urlString.length()-2);
            try{return newResource(file_url).exists();}
            catch(Exception e) {LOG.ignore(e); return false;}
        }
        
        boolean check=checkConnection();
        
        // Is this a root URL?
        if (_jarUrl!=null && _path==null)
        {
            // Then if it exists it is a directory
            _directory=check;
            return true;
        }
        else 
        {
            // Can we find a file for it?
            boolean close_jar_file= false;
            JarFile jar_file=null;
            if (check)
                // Yes
                jar_file=_jarFile;
            else
            {
                // No - so lets look if the root entry exists.
                try
                {
                    JarURLConnection c=(JarURLConnection)((new URL(_jarUrl)).openConnection());
                    c.setUseCaches(getUseCaches());
                    jar_file=c.getJarFile();
                    close_jar_file = !getUseCaches();
                }
                catch(Exception e)
                {
                    LOG.ignore(e);
                }
            }

            // Do we need to look more closely?
            if (jar_file!=null && _entry==null && !_directory)
            {
                // OK - we have a JarFile, lets look for the entry
                JarEntry entry = jar_file.getJarEntry(_path);
                if (entry == null) 
                {
                    // the entry does not exist
                    _exists = false;
                } 
                else if (entry.isDirectory()) 
                {
                    _directory = true;
                    _entry = entry;
                } 
                else 
                {
                    // Let's confirm is a file
                    JarEntry directory = jar_file.getJarEntry(_path + '/');
                    if (directory != null) 
                    {
                        _directory = true;
                        _entry = directory;
                    } 
                    else 
                    {
                        // OK is a file
                      _directory = false;
                      _entry = entry;
                    }
                }
            }

            if(close_jar_file && jar_file!=null) 
            {
                try 
                {
                    jar_file.close();
                } 
                catch (IOException ioe) 
                {
                    LOG.ignore(ioe);
                }
            }
        }
        
        _exists= ( _directory || _entry!=null);
        return _exists;
    }

    
    /* ------------------------------------------------------------ */
    /**
     * Returns true if the represented resource is a container/directory.
     * If the resource is not a file, resources ending with "/" are
     * considered directories.
     */
    @Override
    public boolean isDirectory()
    {
        return _urlString.endsWith("/") || exists() && _directory;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * Returns the last modified time
     */
    @Override
    public long lastModified()
    {
        if (checkConnection() && _file!=null)
        {
            if (exists() && _entry!=null)
                return _entry.getTime();
            return _file.lastModified();
        }
        return -1;
    }

    /* ------------------------------------------------------------ */
    @Override
    public synchronized String[] list()
    {
        if (isDirectory() && _list==null)
        {
            List<String> list = null;
            try
            {
                list = listEntries();
            }
            catch (Exception e)
            {
                //Sun's JarURLConnection impl for jar: protocol will close a JarFile in its connect() method if
                //useCaches == false (eg someone called URLConnection with defaultUseCaches==true).
                //As their sun.net.www.protocol.jar package caches JarFiles and/or connections, we can wind up in 
                //the situation where the JarFile we have remembered in our _jarFile member has actually been closed
                //by other code.
                //So, do one retry to drop a connection and get a fresh JarFile
                LOG.warn("Retrying list:"+e);
                LOG.debug(e);
                close();
                list = listEntries();
            }

            if (list != null)
            {
                _list=new String[list.size()];
                list.toArray(_list);
            }  
        }
        return _list;
    }
    
    
    /* ------------------------------------------------------------ */
    private List<String> listEntries ()
    {
        checkConnection();
        
        ArrayList<String> list = new ArrayList<String>(32);
        JarFile jarFile=_jarFile;
        if(jarFile==null)
        {
            try
            {
                JarURLConnection jc=(JarURLConnection)((new URL(_jarUrl)).openConnection());
                jc.setUseCaches(getUseCaches());
                jarFile=jc.getJarFile();
            }
            catch(Exception e)
            {

                e.printStackTrace();
                 LOG.ignore(e);
            }
                if(jarFile==null)
                    throw new IllegalStateException();
        }
        
        Enumeration<JarEntry> e=jarFile.entries();
        String dir=_urlString.substring(_urlString.lastIndexOf("!/")+2);
        while(e.hasMoreElements())
        {
            JarEntry entry = e.nextElement();               
            String name=entry.getName().replace('\\','/');               
            if(!name.startsWith(dir) || name.length()==dir.length())
            {
                continue;
            }
            String listName=name.substring(dir.length());               
            int dash=listName.indexOf('/');
            if (dash>=0)
            {
                //when listing jar:file urls, you get back one
                //entry for the dir itself, which we ignore
                if (dash==0 && listName.length()==1)
                    continue;
                //when listing jar:file urls, all files and
                //subdirs have a leading /, which we remove
                if (dash==0)
                    listName=listName.substring(dash+1, listName.length());
                else
                    listName=listName.substring(0,dash+1);
                
                if (list.contains(listName))
                    continue;
            }
            
            list.add(listName);
        }
        
        return list;
    }
    
    
    
    
    
    /* ------------------------------------------------------------ */
    /**
     * Return the length of the resource
     */
    @Override
    public long length()
    {
        if (isDirectory())
            return -1;

        if (_entry!=null)
            return _entry.getSize();
        
        return -1;
    }

    
    /**
     * Take a Resource that possibly might use URLConnection caching
     * and turn it into one that doesn't.
     * @param resource the JarFileResource to obtain without URLConnection caching. 
     * @return the non-caching resource
     */
    public static Resource getNonCachingResource (Resource resource)
    {
        if (!(resource instanceof JarFileResource))
            return resource;
        
        JarFileResource oldResource = (JarFileResource)resource;
        
        JarFileResource newResource = new JarFileResource(oldResource.getURL(), false);
        return newResource;
    }
    
    /**
     * Check if this jar:file: resource is contained in the
     * named resource. Eg <code>jar:file:///a/b/c/foo.jar!/x.html</code> isContainedIn <code>file:///a/b/c/foo.jar</code>
     * @param resource the resource to test for
     * @return true if resource is contained in the named resource
     * @throws MalformedURLException if unable to process is contained due to invalid URL format
     */
    @Override
    public boolean isContainedIn (Resource resource) 
    throws MalformedURLException
    {
        String string = _urlString;
        int index = string.lastIndexOf("!/");
        if (index > 0)
            string = string.substring(0,index);
        if (string.startsWith("jar:"))
            string = string.substring(4);
        URL url = new URL(string);
        return url.sameFile(resource.getURI().toURL());     
    }
}
