/*
 *  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.internal.nls.Messages;
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;
        }
    }

    /**
     * Answers 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;
    }

    /**
     * Answers 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() {
                                try {
                                    File tempJar = File.createTempFile(
                                            "hyjar_", ".tmp", null);
                                    tempJar.deleteOnExit();
                                    FileOutputStream 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();
                                    return new JarFile(tempJar, true,
                                            ZipFile.OPEN_READ
                                                    | ZipFile.OPEN_DELETE);
                                } catch (IOException e) {
                                    return null;
                                }
                            }
                        });
            } finally {
                if (is != null) {
                    is.close();
                }
            }
        }

        return jar;
    }

    /**
     * Answers 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) {
            // luni.33=Inputstream of the JarURLConnection has been closed
            throw new IllegalStateException(Messages.getString("luni.33")); //$NON-NLS-1$
        }
        connect();
        if (jarInput != null) {
            return jarInput;
        }
        if (jarEntry == null) {
            // luni.34=Jar entry not specified
            throw new IOException(Messages.getString("luni.34")); //$NON-NLS-1$
        }
        return jarInput = new JarURLConnectionInputStream(jarFile
                .getInputStream(jarEntry), jarFile);
    }

    /**
     * Answers 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;
    }

    /**
     * Answers 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;
    }

    /**
     * Answers 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();
    }

    /**
     * Answers 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);
        }
    }
}
