/*
 *  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.
 */

package org.apache.harmony.luni.internal.net.www.protocol.jar;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ContentHandler;
import java.net.ContentHandlerFactory;
import java.net.JarURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipFile;

import org.apache.harmony.luni.util.Msg;
import org.apache.harmony.luni.util.Util;

/**
 * This subclass extends {@code URLConnection}.
 * <p>
 *
 * This class is responsible for connecting and retrieving resources from a Jar
 * file which can be anywhere that can be referred to by an URL.
 */
public class JarURLConnectionImpl extends JarURLConnection {

    static HashMap<URL, JarFile> jarCache = new HashMap<URL, JarFile>();

    private URL jarFileURL;

    private InputStream jarInput;

    private JarFile jarFile;

    private JarEntry jarEntry;

    private boolean closed;

    /**
     * @param url
     *            the URL of the JAR
     * @throws MalformedURLException
     *             if the URL is malformed
     * @throws IOException
     *             if there is a problem opening the connection.
     */
    public JarURLConnectionImpl(URL url) throws MalformedURLException,
            IOException {
        super(url);
        jarFileURL = getJarFileURL();
        jarFileURLConnection = jarFileURL.openConnection();
    }

    /**
     * @see java.net.URLConnection#connect()
     */
    @Override
    public void connect() throws IOException {
        if (!connected) {
            findJarFile(); // ensure the file can be found
            findJarEntry(); // ensure the entry, if any, can be found
            connected = true;
        }
    }

    /**
     * Returns the Jar file referred by this {@code URLConnection}.
     * 
     * @return the JAR file referenced by this connection
     *
     * @throws IOException
     *             thrown if an IO error occurs while connecting to the
     *             resource.
     */
    @Override
    public JarFile getJarFile() throws IOException {
        connect();
        return jarFile;
    }

    /**
     * Returns the Jar file referred by this {@code URLConnection}
     * 
     * @throws IOException
     *             if an IO error occurs while connecting to the resource.
     */
    private void findJarFile() throws IOException {
        JarFile jar = null;
        if (getUseCaches()) {
            synchronized (jarCache) {
                jarFile = jarCache.get(jarFileURL);
            }
            if (jarFile == null) {
                jar = openJarFile();
                synchronized (jarCache) {
                    jarFile = jarCache.get(jarFileURL);
                    if (jarFile == null) {
                        jarCache.put(jarFileURL, jar);
                        jarFile = jar;
                    } else {
                        jar.close();
                    }
                }
            }
        } else {
            jarFile = openJarFile();
        }

        if (jarFile == null) {
            throw new IOException();
        }
    }

    @SuppressWarnings("nls")
    JarFile openJarFile() throws IOException {
        JarFile jar = null;
        if (jarFileURL.getProtocol().equals("file")) {
            jar = new JarFile(new File(Util.decode(jarFileURL.getFile(), false,
                    "UTF-8")), true, ZipFile.OPEN_READ);
        } else {
            final InputStream is = jarFileURL.openConnection().getInputStream();
            try {
                jar = AccessController
                        .doPrivileged(new PrivilegedAction<JarFile>() {
                            public JarFile run() {
                                FileOutputStream fos = null;
                                JarFile result = null;
                                try {
                                    File tempJar = File.createTempFile("hyjar_", ".tmp", null);
                                    tempJar.deleteOnExit();
                                    fos = new FileOutputStream(tempJar);
                                    byte[] buf = new byte[4096];
                                    int nbytes = 0;
                                    while ((nbytes = is.read(buf)) > -1) {
                                        fos.write(buf, 0, nbytes);
                                    }
                                    fos.close();
                                    result = new JarFile(tempJar, true,
                                            ZipFile.OPEN_READ | ZipFile.OPEN_DELETE);
                                } catch (IOException e) {
                                    return null;
                                } finally {
                                    if (fos != null) {
                                        try {
                                            fos.close();
                                        } catch (IOException ex) {
                                            result = null;
                                        }
                                    }
                                }
                                return result;
                            }
                        });
            } finally {
                if (is != null) {
                    is.close();
                }
            }
        }

        return jar;
    }

    /**
     * Returns the JarEntry of the entry referenced by this {@code
     * URLConnection}.
     * 
     * @return the JarEntry referenced
     * 
     * @throws IOException
     *             if an IO error occurs while getting the entry
     */
    @Override
    public JarEntry getJarEntry() throws IOException {
        connect();
        return jarEntry;

    }

    /**
     * Look up the JarEntry of the entry referenced by this {@code
     * URLConnection}.
     */
    private void findJarEntry() throws IOException {
        if (getEntryName() == null) {
            return;
        }
        jarEntry = jarFile.getJarEntry(getEntryName());
        if (jarEntry == null) {
            throw new FileNotFoundException(getEntryName());
        }
    }

    /**
     * Creates an input stream for reading from this URL Connection.
     *
     * @return the input stream
     *
     * @throws IOException
     *             if an IO error occurs while connecting to the resource.
     */
    @Override
    public InputStream getInputStream() throws IOException {
        if (closed) {
            // KA027=Inputstream of the JarURLConnection has been closed
            throw new IllegalStateException(Msg.getString("KA027")); //$NON-NLS-1$
        }
        connect();
        if (jarInput != null) {
            return jarInput;
        }
        if (jarEntry == null) {
            // K00fc=Jar entry not specified
            throw new IOException(Msg.getString("K00fc")); //$NON-NLS-1$
        }
        return jarInput = new JarURLConnectionInputStream(jarFile
                .getInputStream(jarEntry), jarFile);
    }

    /**
     * Returns the content type of the resource. For jar file itself
     * "x-java/jar" should be returned, for jar entries the content type of the
     * entry should be returned. Returns non-null results ("content/unknown" for
     * unknown types).
     * 
     * @return the content type
     */
    @Override
    public String getContentType() {
        if (url.getFile().endsWith("!/")) { //$NON-NLS-1$
            // the type for jar file itself is always "x-java/jar"
            return "x-java/jar"; //$NON-NLS-1$
        }
        String cType = null;
        String entryName = getEntryName();

        if (entryName != null) {
            // if there is an Jar Entry, get the content type from the name
            cType = guessContentTypeFromName(entryName);
        } else {
            try {
                connect();
                cType = jarFileURLConnection.getContentType();
            } catch (IOException ioe) {
                // Ignore
            }
        }
        if (cType == null) {
            cType = "content/unknown"; //$NON-NLS-1$
        }
        return cType;
    }

    /**
     * Returns the content length of the resource. Test cases reveal that if the
     * URL is referring to a Jar file, this method answers a content-length
     * returned by URLConnection. For jar entry it should return it's size.
     * Otherwise, it will return -1.
     *
     * @return the content length
     */
    @Override
    public int getContentLength() {
        try {
            connect();
            if (jarEntry == null) {
                return jarFileURLConnection.getContentLength();
            }
            return (int) getJarEntry().getSize();
        } catch (IOException e) {
            // Ignored
        }
        return -1;
    }

    /**
     * Returns the object pointed by this {@code URL}. If this URLConnection is
     * pointing to a Jar File (no Jar Entry), this method will return a {@code
     * JarFile} If there is a Jar Entry, it will return the object corresponding
     * to the Jar entry content type.
     * 
     * @return a non-null object
     *
     * @throws IOException
     *             if an IO error occurred
     * 
     * @see ContentHandler
     * @see ContentHandlerFactory
     * @see java.io.IOException
     * @see #setContentHandlerFactory(ContentHandlerFactory)
     */
    @Override
    public Object getContent() throws IOException {
        connect();
        // if there is no Jar Entry, return a JarFile
        if (jarEntry == null) {
            return jarFile;
        }
        return super.getContent();
    }

    /**
     * Returns the permission, in this case the subclass, FilePermission object
     * which represents the permission necessary for this URLConnection to
     * establish the connection.
     *
     * @return the permission required for this URLConnection.
     *
     * @throws IOException
     *             thrown when an IO exception occurs while creating the
     *             permission.
     */

    @Override
    public Permission getPermission() throws IOException {
        return jarFileURLConnection.getPermission();
    }

    @Override
    public boolean getUseCaches() {
        return jarFileURLConnection.getUseCaches();
    }

    @Override
    public void setUseCaches(boolean usecaches) {
        jarFileURLConnection.setUseCaches(usecaches);
    }

    @Override
    public boolean getDefaultUseCaches() {
        return jarFileURLConnection.getDefaultUseCaches();
    }

    @Override
    public void setDefaultUseCaches(boolean defaultusecaches) {
        jarFileURLConnection.setDefaultUseCaches(defaultusecaches);
    }

    /**
     * Closes the cached files.
     */
    public static void closeCachedFiles() {
        Set<Map.Entry<URL, JarFile>> s = jarCache.entrySet();
        synchronized (jarCache) {
            Iterator<Map.Entry<URL, JarFile>> i = s.iterator();
            while (i.hasNext()) {
                try {
                    ZipFile zip = i.next().getValue();
                    if (zip != null) {
                        zip.close();
                    }
                } catch (IOException e) {
                    // Ignored
                }
            }
        }
    }

    private class JarURLConnectionInputStream extends FilterInputStream {
        InputStream inputStream;

        JarFile jarFile;

        protected JarURLConnectionInputStream(InputStream in, JarFile file) {
            super(in);
            inputStream = in;
            jarFile = file;
        }

        @Override
        public void close() throws IOException {
            super.close();
            if (!getUseCaches()) {
                closed = true;
                jarFile.close();
            }
        }

        @Override
        public int read() throws IOException {
            return inputStream.read();
        }

        @Override
        public int read(byte[] buf, int off, int nbytes) throws IOException {
            return inputStream.read(buf, off, nbytes);
        }

        @Override
        public long skip(long nbytes) throws IOException {
            return inputStream.skip(nbytes);
        }
    }
}
