/*
 * 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.felix.framework;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.security.Permission;

import org.apache.felix.framework.util.Util;
import org.osgi.framework.Bundle;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleRevisions;
import org.osgi.framework.wiring.BundleWiring;

class URLHandlersBundleURLConnection extends URLConnection
{
    private Felix m_framework;
    private BundleRevision m_targetRevision;
    private int m_classPathIdx = -1;
    private int m_contentLength;
    private long m_contentTime;
    private String m_contentType;
    private InputStream m_is;
    private final String m_path;

    public URLHandlersBundleURLConnection(URL url, Felix framework)
        throws IOException
    {
        super(url);

        String urlString = url.toExternalForm();

        m_path = urlString.substring(urlString.indexOf(url.getPath()));

        // If this is an attempt to create a connection to the root of
        // the bundle, then throw an exception since this isn't possible.
        // We only allow "/" as a valid URL so it can be used as context
        // for creating other URLs.
        if ((m_path == null) || (m_path.length() == 0) || m_path.equals("/"))
        {
            throw new IOException("Resource does not exist: " + url);
        }

        m_framework = framework;

        // If we don't have a framework instance, try to find
        // one from the call context.
        if (m_framework == null)
        {
            Object tmp = URLHandlers.getFrameworkFromContext(Util.getFrameworkUUIDFromURL(url.getHost()));
            if (tmp instanceof Felix)
            {
                m_framework = (Felix) tmp;
            }
        }

        // If there is still no framework, then error.
        if (m_framework == null)
        {
            throw new IOException("Unable to find framework for URL: " + url);
        }
        // Verify that the resource pointed to by the URL exists.
        // The URL is constructed like this:
        //     bundle://<revision-id>:<bundle-classpath-index>/<resource-path>
        // Where <revision-id> = <bundle-id>.<revision>
        long bundleId = Util.getBundleIdFromRevisionId(Util.getRevisionIdFromURL(url.getHost()));
        Bundle bundle = m_framework.getBundle(bundleId);
        if (bundle == null)
        {
            throw new IOException("No bundle associated with resource: " + url);
        }
        m_contentTime = bundle.getLastModified();

        // Get the bundle's revisions to find the target revision.
        BundleRevisions revisions = bundle.adapt(BundleRevisions.class);
        if ((revisions == null) || revisions.getRevisions().isEmpty())
        {
            throw new IOException("Resource does not exist: " + url);
        }

        // Search for matching revision name.
        for (BundleRevision br : revisions.getRevisions())
        {
            if (((BundleRevisionImpl) br).getId().equals(url.getHost()))
            {
                m_targetRevision = br;
                break;
            }
        }

        // If not found, assume the current revision.
        if (m_targetRevision == null)
        {
            m_targetRevision = revisions.getRevisions().get(0);
        }

        // If the resource cannot be found at the current class path index,
        // then search them all in order to see if it can be found. This is
        // necessary since the user might create a resource URL from another
        // resource URL and not realize they have the wrong class path entry.
        // Of course, this approach won't work in cases where there are multiple
        // resources with the same path, since it will always find the first
        // one on the class path.
        m_classPathIdx = url.getPort();
        if (m_classPathIdx < 0)
        {
            m_classPathIdx = 0;
        }
        if (!((BundleRevisionImpl) m_targetRevision)
            .hasInputStream(m_classPathIdx, m_path))
        {
            BundleWiring wiring = m_targetRevision.getWiring();
            ClassLoader cl = (wiring != null) ? wiring.getClassLoader() : null;
            URL newurl = (cl != null) ? cl.getResource(m_path) : null;
            if (newurl == null)
            {
                throw new IOException("Resource does not exist: " + url);
            }
            m_classPathIdx = newurl.getPort();
        }
    }

    public synchronized void connect() throws IOException
    {
        if (!connected)
        {
            if ((m_targetRevision == null) || (m_classPathIdx < 0))
            {
                throw new IOException("Resource does not exist: " + url);
            }
            m_is = ((BundleRevisionImpl)
                m_targetRevision).getInputStream(m_classPathIdx, m_path);
            m_contentLength = (m_is == null) ? 0 : m_is.available();
            m_contentType = URLConnection.guessContentTypeFromName(m_path);
            connected = true;
        }
    }

    public InputStream getInputStream()
        throws IOException
    {
        connect();

        return m_is;
    }

    public int getContentLength()
    {
        try
        {
            connect();
        }
        catch(IOException ex)
        {
            return -1;
        }

        return m_contentLength;
    }

    public long getContentLengthLong()
    {
        return getContentLength();
    }

    public long getLastModified()
    {
        try
        {
            connect();
        }
        catch(IOException ex)
        {
            return 0;
        }

        if (m_contentTime != -1L)
        {
            return m_contentTime;
        }
        else
        {
            return 0L;
        }
    }

    public String getContentType()
    {
        try
        {
            connect();
        }
        catch (IOException ex)
        {
            return null;
        }

        return m_contentType;
    }

    public Permission getPermission()
    {
        // TODO: SECURITY - This should probably return a FilePermission
        // to access the bundle JAR file, but we don't have the
        // necessary information here to construct the absolute
        // path of the JAR file...so it would take some
        // re-arranging to get this to work.
        return null;
    }

    /**
     * Retrieve the entry as a URL using standard protocols such as file: and jar:
     *
     * @return the local URL
     */
    URL getLocalURL()
    {
        if ((m_targetRevision == null) || (m_classPathIdx < 0))
        {
            return url;
        }
        return ((BundleRevisionImpl)
            m_targetRevision).getLocalURL(m_classPathIdx, m_path);
    }
}