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

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

        // 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.
        String path = url.getPath();
        if ((path == null) || (path.length() == 0) || 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, url.getPath()))
        {
            BundleWiring wiring = m_targetRevision.getWiring();
            ClassLoader cl = (wiring != null) ? wiring.getClassLoader() : null;
            URL newurl = (cl != null) ? cl.getResource(url.getPath()) : 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, url.getPath());
            m_contentLength = (m_is == null) ? 0 : m_is.available();
            m_contentType = URLConnection.guessContentTypeFromName(url.getFile());
            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, url.getPath());
    }
}