//
//  ========================================================================
//  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.osgi.boot.utils.internal;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.zip.ZipFile;

import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.resource.Resource;
import org.osgi.framework.Bundle;

/**
 * DefaultFileLocatorHelper
 * <p> 
 * From a bundle to its location on the filesystem. Assumes the bundle is not a
 * jar.
 */
public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
{

    // hack to locate the file-system directly from the bundle.
    // support equinox, felix and nuxeo's osgi implementations.
    // not tested on nuxeo and felix just yet.
    // The url nuxeo and felix return is created directly from the File so it
    // should work.
    private static Field BUNDLE_ENTRY_FIELD = null;

    private static Field FILE_FIELD = null;

    private static Field BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = null;// ZipBundleFile

    // inside
    // DirZipBundleEntry

    private static Field ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = null;// ZipFile
    
    private static final String[] FILE_BUNDLE_ENTRY_CLASSES = {"org.eclipse.osgi.baseadaptor.bundlefile.FileBundleEntry","org.eclipse.osgi.storage.bundlefile.FileBundleEntry"};
    private static final String[] ZIP_BUNDLE_ENTRY_CLASSES = {"org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry","org.eclipse.osgi.storage.bundlefile.ZipBundleEntry"};
    private static final String[] DIR_ZIP_BUNDLE_ENTRY_CLASSES = {"org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry","org.eclipse.osgi.storage.bundlefile.DirZipBundleEntry"};
    private static final String[] BUNDLE_URL_CONNECTION_CLASSES = {"org.eclipse.osgi.framework.internal.core.BundleURLConnection", "org.eclipse.osgi.storage.url.BundleURLConnection"};


    public static boolean match (String name, String... names)
    {
        if (name == null || names == null)
            return false;
        boolean matched = false;
        for (int i=0; i< names.length && !matched; i++)
            if (name.equals(names[i]))
                matched = true;
        return matched;
    }
    
    
    /**
     * Works with equinox, felix, nuxeo and probably more. Not exactly in the
     * spirit of OSGi but quite necessary to support self-contained webapps and
     * other situations.
     * 
     * @param bundle The bundle
     * @return Its installation location as a file.
     * @throws Exception if unable to get the bundle install location
     */
    public File getBundleInstallLocation(Bundle bundle) throws Exception
    {
        // String installedBundles = System.getProperty("osgi.bundles");
        // grab the MANIFEST.MF's url
        // and then do what it takes.
        URL url = bundle.getEntry("/META-INF/MANIFEST.MF");

        if (url.getProtocol().equals("file"))
        {
            // some osgi frameworks do use the file protocol directly in some
            // situations. Do use the FileResource to transform the URL into a
            // File: URL#toURI is broken
            return new PathResource(url).getFile().getParentFile().getParentFile();
        }
        else if (url.getProtocol().equals("bundleentry"))
        {
            // say hello to equinox who has its own protocol.
            // we use introspection like there is no tomorrow to get access to
            // the File

            URLConnection con = url.openConnection();
            con.setUseCaches(Resource.getDefaultUseCaches()); // work around
            // problems where
            // url connections
            // cache
            // references to
            // jars

            if (BUNDLE_ENTRY_FIELD == null)
            {
                BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
                BUNDLE_ENTRY_FIELD.setAccessible(true);
            }
            Object bundleEntry = BUNDLE_ENTRY_FIELD.get(con);
           
            if (match(bundleEntry.getClass().getName(), FILE_BUNDLE_ENTRY_CLASSES))
            {
                if (FILE_FIELD == null)
                {
                    FILE_FIELD = bundleEntry.getClass().getDeclaredField("file");
                    FILE_FIELD.setAccessible(true);
                }
                File f = (File) FILE_FIELD.get(bundleEntry);
                return f.getParentFile().getParentFile();
            }
            else if (match(bundleEntry.getClass().getName(), ZIP_BUNDLE_ENTRY_CLASSES))
            {
                url = bundle.getEntry("/");

                con = url.openConnection();
                con.setDefaultUseCaches(Resource.getDefaultUseCaches());

                if (BUNDLE_ENTRY_FIELD == null)
                {// this one will be a DirZipBundleEntry
                    BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
                    BUNDLE_ENTRY_FIELD.setAccessible(true);
                }
                bundleEntry = BUNDLE_ENTRY_FIELD.get(con);
                if (BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY == null)
                {
                    BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = bundleEntry.getClass().getDeclaredField("bundleFile");
                    BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.setAccessible(true);
                }
                Object zipBundleFile = BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.get(bundleEntry);
                if (ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE == null)
                {
                    ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = zipBundleFile.getClass().getDeclaredField("zipFile");
                    ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.setAccessible(true);
                }
                ZipFile zipFile = (ZipFile) ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile);
                return new File(zipFile.getName());
            }
            else if (match (bundleEntry.getClass().getName(), DIR_ZIP_BUNDLE_ENTRY_CLASSES))
            {
                // that will not happen as we did ask for the manifest not a
                // directory.
            }
        }
        else if ("bundle".equals(url.getProtocol()))
        {
            // observed this on felix-2.0.0
            String location = bundle.getLocation();
            if (location.startsWith("file:/"))
            {
                URI uri = new URI(URIUtil.encodePath(location));
                return new File(uri);
            }
            else if (location.startsWith("file:"))
            {
                // location defined in the BundleArchive m_bundleArchive
                // it is relative to relative to the BundleArchive's
                // m_archiveRootDir
                File res = new File(location.substring("file:".length()));
                if (!res.exists()) { return null;
                // Object bundleArchive = getFelixBundleArchive(bundle);
                // File archiveRoot =
                // getFelixBundleArchiveRootDir(bundleArchive);
                // String currentLocation =
                // getFelixBundleArchiveCurrentLocation(bundleArchive);
                // System.err.println("Got the archive root " +
                // archiveRoot.getAbsolutePath()
                // + " current location " + currentLocation +
                // " is directory ?");
                // res = new File(archiveRoot, currentLocation != null
                // ? currentLocation : location.substring("file:".length()));
                }
                return res;
            }
            else if (location.startsWith("reference:file:"))
            {
                location = URLDecoder.decode(location.substring("reference:".length()), "UTF-8");
                File file = new File(location.substring("file:".length()));
                return file;
            }
        }
        return null;
    }

    /**
     * Locate a file inside a bundle.
     * 
     * @param bundle the bundle
     * @param path the path
     * @return file object
     * @throws Exception if unable to get the file in the bundle
     */
    public File getFileInBundle(Bundle bundle, String path) throws Exception
    {
        if (path != null && path.length() > 0 && path.charAt(0) == '/')
        {
            path = path.substring(1);
        }
        File bundleInstall = getBundleInstallLocation(bundle);
        File webapp = path != null && path.length() != 0 ? new File(bundleInstall, path) : bundleInstall;
        if (!webapp.exists()) { throw new IllegalArgumentException("Unable to locate " + path
                                                                   + " inside "
                                                                   + bundle.getSymbolicName()
                                                                   + " ("
                                                                   + (bundleInstall != null ? bundleInstall.getAbsolutePath() : " no_bundle_location ")
                                                                   + ")"); }
        return webapp;
    }

    /**
     * Helper method equivalent to Bundle#getEntry(String entryPath) except that
     * it searches for entries in the fragments by using the Bundle#findEntries
     * method.
     * 
     * @param bundle the bundle
     * @param entryPath the entry path
     * @return null or all the entries found for that path.
     */
    public Enumeration<URL> findEntries(Bundle bundle, String entryPath)
    {
        int last = entryPath.lastIndexOf('/');
        String path = last != -1 && last < entryPath.length() - 2 ? entryPath.substring(0, last) : "/";
        if (!path.startsWith("/"))
        {
            path = "/" + path;
        }
        String pattern = last != -1 && last < entryPath.length() - 2 ? entryPath.substring(last + 1) : entryPath;
        Enumeration<URL> enUrls = bundle.findEntries(path, pattern, false);
        return enUrls;
    }

    /**
     * If the bundle is a jar, returns the jar. If the bundle is a folder, look
     * inside it and search for jars that it returns.
     * <p>
     * Good enough for our purpose (TldLocationsCache when it scans for tld
     * files inside jars alone. In fact we only support the second situation for
     * development purpose where the bundle was imported in pde and the classes
     * kept in a jar.
     * </p>
     * 
     * @param bundle the bundle
     * @return The jar(s) file that is either the bundle itself, either the jars
     *         embedded inside it.
     */
    public File[] locateJarsInsideBundle(Bundle bundle) throws Exception
    {
        File jasperLocation = getBundleInstallLocation(bundle);
        if (jasperLocation.isDirectory())
        {
            // try to find the jar files inside this folder
            ArrayList<File> urls = new ArrayList<File>();
            for (File f : jasperLocation.listFiles())
            {
                if (f.getName().endsWith(".jar") && f.isFile())
                {
                    urls.add(f);
                }
                else if (f.isDirectory() && f.getName().equals("lib"))
                {
                    for (File f2 : jasperLocation.listFiles())
                    {
                        if (f2.getName().endsWith(".jar") && f2.isFile())
                        {
                            urls.add(f2);
                        }
                    }
                }
            }
            return urls.toArray(new File[urls.size()]);
        }
        else
        {
            return new File[] { jasperLocation };
        }
    }

    // introspection on equinox to invoke the getLocalURL method on
    // BundleURLConnection
    // equivalent to using the FileLocator without depending on an equinox
    // class.
    private static Method BUNDLE_URL_CONNECTION_getLocalURL = null;

    private static Method BUNDLE_URL_CONNECTION_getFileURL = null;

    /**
     * Only useful for equinox: on felix we get the file:// or jar:// url
     * already. Other OSGi implementations have not been tested
     * <p>
     * Get a URL to the bundle entry that uses a common protocol (i.e. file:
     * jar: or http: etc.).
     * </p>
     * 
     * @return a URL to the bundle entry that uses a common protocol
     */
    public URL getLocalURL(URL url)
    throws Exception
    {
        if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol()))
        {

            URLConnection conn = url.openConnection();
            conn.setDefaultUseCaches(Resource.getDefaultUseCaches());
            if (BUNDLE_URL_CONNECTION_getLocalURL == null && match(conn.getClass().getName(), BUNDLE_URL_CONNECTION_CLASSES))
            {
                BUNDLE_URL_CONNECTION_getLocalURL = conn.getClass().getMethod("getLocalURL", null);
                BUNDLE_URL_CONNECTION_getLocalURL.setAccessible(true);
            }
            if (BUNDLE_URL_CONNECTION_getLocalURL != null) { return (URL) BUNDLE_URL_CONNECTION_getLocalURL.invoke(conn, null); }
        }
        return url;
    }

    /**
     * Only useful for equinox: on felix we get the file:// url already. Other
     * OSGi implementations have not been tested
     * <p>
     * Get a URL to the content of the bundle entry that uses the file:
     * protocol. The content of the bundle entry may be downloaded or extracted
     * to the local file system in order to create a file: URL.
     * 
     * @return a URL to the content of the bundle entry that uses the file:
     *         protocol
     *         </p>
     * @throws Exception if unable to get the file url 
     */
    public URL getFileURL(URL url) throws Exception
 
    {
        if ("bundleresource".equals(url.getProtocol()) || "bundleentry".equals(url.getProtocol()))
        {

            URLConnection conn = url.openConnection();
            conn.setDefaultUseCaches(Resource.getDefaultUseCaches());
            if (BUNDLE_URL_CONNECTION_getFileURL == null 
                && 
                match (conn.getClass().getName(), BUNDLE_URL_CONNECTION_CLASSES))
            {
                BUNDLE_URL_CONNECTION_getFileURL = conn.getClass().getMethod("getFileURL", null);
                BUNDLE_URL_CONNECTION_getFileURL.setAccessible(true);
            }
            if (BUNDLE_URL_CONNECTION_getFileURL != null) { return (URL) BUNDLE_URL_CONNECTION_getFileURL.invoke(conn, null); }

        }
        return url;
    }

}
