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

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;

import org.eclipse.jetty.deploy.App;
import org.eclipse.jetty.deploy.AppProvider;
import org.eclipse.jetty.deploy.DeploymentManager;
import org.eclipse.jetty.osgi.boot.internal.serverfactory.ServerInstanceWrapper;
import org.eclipse.jetty.osgi.boot.internal.webapp.OSGiWebappClassLoader;
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelperFactory;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.ArrayUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.JarResource;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.xml.XmlConfiguration;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.service.packageadmin.PackageAdmin;




/**
 * AbstractWebAppProvider
 *
 * Base class for Jetty DeploymentManager Providers that are capable of deploying a webapp,
 * either from a bundle or an OSGi service.
 * 
 */
public abstract class AbstractWebAppProvider extends AbstractLifeCycle implements AppProvider
{
    private static final Logger LOG = Log.getLogger(AbstractWebAppProvider.class);
    
    public static String __defaultConfigurations[] = {
                                                            "org.eclipse.jetty.osgi.boot.OSGiWebInfConfiguration",
                                                            "org.eclipse.jetty.webapp.WebXmlConfiguration",
                                                            "org.eclipse.jetty.webapp.MetaInfConfiguration",
                                                            "org.eclipse.jetty.webapp.FragmentConfiguration",
                                                            "org.eclipse.jetty.webapp.JettyWebXmlConfiguration"                          
                                                     };
    
    public static void setDefaultConfigurations (String[] defaultConfigs)
    {
        __defaultConfigurations = defaultConfigs;
    }
    
    public static String[] getDefaultConfigurations ()
    {
        List<String> configs = ArrayUtil.asMutableList(__defaultConfigurations);
        if (annotationsAvailable())
        {
            //add before JettyWebXmlConfiguration
            int i = configs.indexOf("org.eclipse.jetty.webapp.JettyWebXmlConfiguration");
            configs.add(i, "org.eclipse.jetty.osgi.annotations.AnnotationConfiguration");
        }
        
        if (jndiAvailable())
        {
            //add in EnvConfiguration and PlusConfiguration just after FragmentConfiguration
            int i = configs.indexOf("org.eclipse.jetty.webapp.FragmentConfiguration");
            configs.add(++i, "org.eclipse.jetty.plus.webapp.EnvConfiguration");
            configs.add(++i, "org.eclipse.jetty.plus.webapp.PlusConfiguration");
        }

        return configs.toArray(new String[configs.size()]);
    }

    private static boolean annotationsAvailable()
    {
        boolean result = false;
        try
        {
            Loader.loadClass(AbstractWebAppProvider.class,"org.eclipse.jetty.annotations.AnnotationConfiguration");
            result = true;
            LOG.debug("Annotation support detected");
        }
        catch (ClassNotFoundException e)
        {
            result = false;
            LOG.debug("No annotation support detected");
        }

        return result;
    }
    
    
    private static boolean jndiAvailable()
    {
        try
        {
            Loader.loadClass(AbstractWebAppProvider.class, "org.eclipse.jetty.plus.jndi.Resource");
            Loader.loadClass(AbstractWebAppProvider.class, "org.eclipse.jetty.plus.webapp.EnvConfiguration");
            LOG.debug("JNDI support detected");
            return true;
        }
        catch (ClassNotFoundException e)
        {
            LOG.debug("No JNDI support detected");
            return false;
        }
    }
    

    private boolean _parentLoaderPriority;

    private String _defaultsDescriptor;

    private boolean _extractWars = true; //See WebAppContext.extractWars

    private String _tldBundles;
    
    private DeploymentManager _deploymentManager;
    
    private String[] _configurationClasses;
    
    private ServerInstanceWrapper _serverWrapper;
    
    /* ------------------------------------------------------------ */
    /**
     * OSGiApp
     *
     *
     */
    public class OSGiApp extends AbstractOSGiApp
    {
        private String _contextPath;
        private String _webAppPath;
        private WebAppContext _webApp;

        public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, String originId)
        {
            super(manager, provider, bundle, originId);
        }
        
        public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String originId)
        {
            super(manager, provider, bundle, properties, originId);
        }
     
        public void setWebAppContext (WebAppContext webApp)
        {
            _webApp = webApp;
        }

        public String getContextPath()
        {
            return _contextPath;
        }

        public void setContextPath(String contextPath)
        {
            this._contextPath = contextPath;
        }

        public String getBundlePath()
        {
            return _webAppPath;
        }

        public void setWebAppPath(String path)
        {
            this._webAppPath = path;
        }
        
        
        public ContextHandler createContextHandler()
        throws Exception
        {
            if (_webApp != null)
            {
                configureWebApp();
                return _webApp;
            }
            
            createWebApp();
            return _webApp;
        }
        
      
        
        protected void createWebApp ()
        throws Exception
        {
            _webApp = newWebApp();
            configureWebApp();
        }
        
        protected WebAppContext newWebApp ()
        {
            WebAppContext webApp = new WebAppContext();
            webApp.setAttribute(OSGiWebappConstants.WATERMARK, OSGiWebappConstants.WATERMARK);

            //make sure we protect also the osgi dirs specified by OSGi Enterprise spec
            String[] targets = webApp.getProtectedTargets();
            String[] updatedTargets = null;
            if (targets != null)
            {
                updatedTargets = new String[targets.length+OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length];
                System.arraycopy(targets, 0, updatedTargets, 0, targets.length);
            }
            else
                updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length];
            System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, targets.length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length);
            webApp.setProtectedTargets(updatedTargets);

           return webApp;
        }


        public void configureWebApp() 
        throws Exception
        {                     
            //TODO turn this around and let any context.xml file get applied first, and have the properties override
            _webApp.setContextPath(_contextPath);
            
            //osgi Enterprise Spec r4 p.427
            _webApp.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, _bundle.getBundleContext());

            String overrideBundleInstallLocation = (String)_properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE);
            File bundleInstallLocation = 
                (overrideBundleInstallLocation == null 
                        ? BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle) 
                        : new File(overrideBundleInstallLocation));
            
            if (LOG.isDebugEnabled())
            {
                LOG.debug("Bundle location is {}, install location: {}", _bundle.getLocation(), bundleInstallLocation);
            }
            
            URL url = null;
            Resource rootResource = Resource.newResource(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(bundleInstallLocation.toURI().toURL()));
            //try and make sure the rootResource is useable - if its a jar then make it a jar file url
            if (rootResource.exists()&& !rootResource.isDirectory() && !rootResource.toString().startsWith("jar:"))
            {
               Resource jarResource = JarResource.newJarResource(rootResource);
               if (jarResource.exists() && jarResource.isDirectory())
                   rootResource = jarResource;
            }
            
            //if the path wasn't set or it was ., then it is the root of the bundle's installed location
            if (_webAppPath == null || _webAppPath.length() == 0 || ".".equals(_webAppPath))
            {
                url = bundleInstallLocation.toURI().toURL();
                if (LOG.isDebugEnabled())
                    LOG.debug("Webapp base using bundle install location: {}", url);
            }
            else
            {
                //Get the location of the root of the webapp inside the installed bundle
                if (_webAppPath.startsWith("/") || _webAppPath.startsWith("file:"))
                {
                    url = new File(_webAppPath).toURI().toURL();
                    if (LOG.isDebugEnabled())
                        LOG.debug("Webapp base using absolute location: {}", url);
                }
                else if (bundleInstallLocation != null && bundleInstallLocation.isDirectory())
                {
                    url = new File(bundleInstallLocation, _webAppPath).toURI().toURL();
                    if (LOG.isDebugEnabled())
                        LOG.debug("Webapp base using path relative to bundle unpacked install location: {}", url);
                }
                else if (bundleInstallLocation != null)
                {
                    Enumeration<URL> urls = BundleFileLocatorHelperFactory.getFactory().getHelper().findEntries(_bundle, _webAppPath);
                    if (urls != null && urls.hasMoreElements())
                    {
                        url = urls.nextElement();
                        if (LOG.isDebugEnabled())
                            LOG.debug("Webapp base using path relative to packed bundle location: {}", url);
                    }
                }
            }

            if (url == null)
            { 
                throw new IllegalArgumentException("Unable to locate " + _webAppPath
                                                   + " in "
                                                   + (bundleInstallLocation != null ? bundleInstallLocation.getAbsolutePath() : "unlocated bundle '" + _bundle.getSymbolicName()+ "'"));
            }

            //Sets the location of the war file
            // converts bundleentry: protocol if necessary
            _webApp.setWar(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(url).toString());

            // Set up what has been configured on the provider
            _webApp.setParentLoaderPriority(isParentLoaderPriority());
            _webApp.setExtractWAR(isExtract());
            if (getConfigurationClasses() != null)
                _webApp.setConfigurationClasses(getConfigurationClasses());
            else
                _webApp.setConfigurationClasses(getDefaultConfigurations());

            if (getDefaultsDescriptor() != null)
                _webApp.setDefaultsDescriptor(getDefaultsDescriptor());

            //Set up configuration from manifest headers
            //extra classpath
            String tmp = (String)_properties.get(OSGiWebappConstants.JETTY_EXTRA_CLASSPATH);
            if (tmp != null)
                _webApp.setExtraClasspath(tmp);

            //web.xml
            tmp = (String)_properties.get(OSGiWebappConstants.JETTY_WEB_XML_PATH);
            if (tmp != null && tmp.trim().length() != 0)
            {
                File webXml = getFile (tmp, bundleInstallLocation);
                if (webXml != null && webXml.exists())
                    _webApp.setDescriptor(webXml.getAbsolutePath());
            }

            //webdefault.xml
            tmp = (String)_properties.get(OSGiWebappConstants.JETTY_DEFAULT_WEB_XML_PATH);
            if (tmp != null)
            {
                File defaultWebXml = getFile (tmp, bundleInstallLocation);
                if (defaultWebXml != null)
                {
                    if (defaultWebXml.exists())
                        _webApp.setDefaultsDescriptor(defaultWebXml.getAbsolutePath());
                    else
                        LOG.warn(defaultWebXml.getAbsolutePath()+" does not exist");
                }
            }

            //Handle Require-TldBundle
            //This is a comma separated list of names of bundles that contain tlds that this webapp uses.
            //We add them to the webapp classloader.
            String requireTldBundles = (String)_properties.get(OSGiWebappConstants.REQUIRE_TLD_BUNDLE);
            String pathsToTldBundles = getPathsToRequiredBundles(requireTldBundles);


            // make sure we provide access to all the jetty bundles by going
            // through this bundle.
            OSGiWebappClassLoader webAppLoader = new OSGiWebappClassLoader(_serverWrapper.getParentClassLoaderForWebapps(), _webApp, _bundle);

            if (pathsToTldBundles != null)
                webAppLoader.addClassPath(pathsToTldBundles);
            _webApp.setClassLoader(webAppLoader);


            // apply any META-INF/context.xml file that is found to configure
            // the webapp first
            applyMetaInfContextXml(rootResource, overrideBundleInstallLocation);

            _webApp.setAttribute(OSGiWebappConstants.REQUIRE_TLD_BUNDLE, requireTldBundles);

            //Set up some attributes
            // rfc66
            _webApp.setAttribute(OSGiWebappConstants.RFC66_OSGI_BUNDLE_CONTEXT, _bundle.getBundleContext());

            // spring-dm-1.2.1 looks for the BundleContext as a different attribute.
            // not a spec... but if we want to support
            // org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext
            // then we need to do this to:
            _webApp.setAttribute("org.springframework.osgi.web." + BundleContext.class.getName(), _bundle.getBundleContext());

            // also pass the bundle directly. sometimes a bundle does not have a
            // bundlecontext.
            // it is still useful to have access to the Bundle from the servlet
            // context.
            _webApp.setAttribute(OSGiWebappConstants.JETTY_OSGI_BUNDLE, _bundle);
        }

        protected String getPathsToRequiredBundles (String requireTldBundles)
        throws Exception
        {
            if (requireTldBundles == null) return null;

            ServiceReference ref = _bundle.getBundleContext().getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName());
            PackageAdmin packageAdmin = (ref == null) ? null : (PackageAdmin)_bundle.getBundleContext().getService(ref);
            if (packageAdmin == null)
                throw new IllegalStateException("Unable to get PackageAdmin reference to locate required Tld bundles");

            StringBuilder paths = new StringBuilder();         
            String[] symbNames = requireTldBundles.split("[, ]");

            for (String symbName : symbNames)
            {
                Bundle[] bs = packageAdmin.getBundles(symbName, null);
                if (bs == null || bs.length == 0) 
                { 
                    throw new IllegalArgumentException("Unable to locate the bundle '" + symbName
                                                       + "' specified by "
                                                       + OSGiWebappConstants.REQUIRE_TLD_BUNDLE
                                                       + " in manifest of "
                                                       + (_bundle == null ? "unknown" : _bundle.getSymbolicName())); 
                }

                File f = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(bs[0]);
                if (paths.length() > 0) paths.append(", ");
                paths.append(f.toURI().toURL().toString());
                LOG.debug("getPathsToRequiredBundles: bundle path=" + bs[0].getLocation() + " uri=" + f.toURI());
            }

            return paths.toString();
        }
        
        
        protected void applyMetaInfContextXml(Resource rootResource, String overrideBundleInstallLocation)
        throws Exception
        {
            if (_bundle == null) return;
            if (_webApp == null) return;

            ClassLoader cl = Thread.currentThread().getContextClassLoader();
            LOG.debug("Context classloader = " + cl);
            try
            {
               
                Thread.currentThread().setContextClassLoader(_webApp.getClassLoader());

                //TODO replace this with getting the InputStream so we don't cache in URL
                //Try looking for a context xml file in META-INF with a specific name
                URL contextXmlUrl = _bundle.getEntry("/META-INF/jetty-webapp-context.xml");
                
                if (contextXmlUrl == null)
                {
                    //Didn't find specially named file, try looking for a property that names a context xml file to use
                    if (_properties != null)
                    {
                        String tmp = (String)_properties.get(OSGiWebappConstants.JETTY_CONTEXT_FILE_PATH);
                        if (tmp != null)
                        {
                            String[] filenames = tmp.split("[,;]");
                            if (filenames != null && filenames.length > 0)
                            {
                                String filename = filenames[0]; //should only be 1 filename in this usage
                                String jettyHome = (String)getServerInstanceWrapper().getServer().getAttribute(OSGiServerConstants.JETTY_HOME);
                                if (jettyHome == null)
                                    jettyHome =  System.getProperty(OSGiServerConstants.JETTY_HOME);
                                Resource res = findFile(filename, jettyHome, overrideBundleInstallLocation, _bundle);
                                if (res != null)
                                    contextXmlUrl = res.getURL();
                            }
                        }
                    }
                }
                if (contextXmlUrl == null) return;

                // Apply it just as the standard jetty ContextProvider would do
                LOG.info("Applying " + contextXmlUrl + " to " + _webApp);

                XmlConfiguration xmlConfiguration = new XmlConfiguration(contextXmlUrl);
                HashMap properties = new HashMap();
                properties.put("Server", getDeploymentManager().getServer());
                properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString());
                properties.put(OSGiServerConstants.JETTY_HOME, getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME));
                xmlConfiguration.getProperties().putAll(properties);
                xmlConfiguration.configure(_webApp);
            }
            finally
            {
                Thread.currentThread().setContextClassLoader(cl);
            }
        }
        
        private File getFile (String file, File bundleInstall)
        {
            if (file == null)
                return null;

            if (file.startsWith("/") || file.startsWith("file:/")) //absolute location
                return new File(file);
            else
            {
                //relative location
                //try inside the bundle first
                File f = new File (bundleInstall, file);
                if (f.exists()) return f;
                String jettyHome = (String)getDeploymentManager().getServer().getAttribute(OSGiServerConstants.JETTY_HOME);
                if (jettyHome != null)
                    return new File(jettyHome, file);
            }
            
            return null;
        }
    }
   
    /* ------------------------------------------------------------ */
    public AbstractWebAppProvider (ServerInstanceWrapper wrapper)
    {
        _serverWrapper = wrapper;
    }
    
    
    
    /* ------------------------------------------------------------ */
    /**
     * Get the parentLoaderPriority.
     * 
     * @return the parentLoaderPriority
     */
    public boolean isParentLoaderPriority()
    {
        return _parentLoaderPriority;
    }

    /* ------------------------------------------------------------ */
    /**
     * Set the parentLoaderPriority.
     * 
     * @param parentLoaderPriority the parentLoaderPriority to set
     */
    public void setParentLoaderPriority(boolean parentLoaderPriority)
    {
        _parentLoaderPriority = parentLoaderPriority;
    }

    /* ------------------------------------------------------------ */
    /**
     * Get the defaultsDescriptor.
     * 
     * @return the defaultsDescriptor
     */
    public String getDefaultsDescriptor()
    {
        return _defaultsDescriptor;
    }

    /* ------------------------------------------------------------ */
    /**
     * Set the defaultsDescriptor.
     * 
     * @param defaultsDescriptor the defaultsDescriptor to set
     */
    public void setDefaultsDescriptor(String defaultsDescriptor)
    {
        _defaultsDescriptor = defaultsDescriptor;
    }
    
    
    /* ------------------------------------------------------------ */
    public boolean isExtract()
    {
        return _extractWars;
    }
    
    
    /* ------------------------------------------------------------ */
    public void setExtract(boolean extract)
    {
        _extractWars = extract;
    }
    
    
    /* ------------------------------------------------------------ */
    /**
     * @param tldBundles Comma separated list of bundles that contain tld jars
     *            that should be setup on the jetty instances created here.
     */
    public void setTldBundles(String tldBundles)
    {
        _tldBundles = tldBundles;
    }
    
    
    /* ------------------------------------------------------------ */
    /**
     * @return The list of bundles that contain tld jars that should be setup on
     *         the jetty instances created here.
     */
    public String getTldBundles()
    {
        return _tldBundles;
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param configurations The configuration class names.
     */
    public void setConfigurationClasses(String[] configurations)
    {
        _configurationClasses = configurations == null ? null : (String[]) configurations.clone();
    }

    /* ------------------------------------------------------------ */
    /**
     * 
     */
    public String[] getConfigurationClasses()
    {
        return _configurationClasses;
    }

    /* ------------------------------------------------------------ */
    public void setServerInstanceWrapper(ServerInstanceWrapper wrapper)
    {
        _serverWrapper = wrapper;
    }

    public ServerInstanceWrapper getServerInstanceWrapper()
    {
        return _serverWrapper;
    }

    /* ------------------------------------------------------------ */
    /**
     * @return
     */
    public DeploymentManager getDeploymentManager()
    {
        return _deploymentManager;
    }

    /* ------------------------------------------------------------ */
    /** 
     * @see org.eclipse.jetty.deploy.AppProvider#setDeploymentManager(org.eclipse.jetty.deploy.DeploymentManager)
     */
    public void setDeploymentManager(DeploymentManager deploymentManager)
    {
        _deploymentManager = deploymentManager;
    }
    
    
    /* ------------------------------------------------------------ */
    public ContextHandler createContextHandler(App app) throws Exception
    {
        if (app == null)
            return null;
        if (!(app instanceof OSGiApp))
            throw new IllegalStateException(app+" is not a BundleApp");

        //Create a WebAppContext suitable to deploy in OSGi
        ContextHandler ch = ((OSGiApp)app).createContextHandler();
        return ch;
    }

    
    /* ------------------------------------------------------------ */
    public static String getOriginId(Bundle contributor, String path)
    {
        return contributor.getSymbolicName() + "-" + contributor.getVersion().toString() + (path.startsWith("/") ? path : "/" + path);
    }
    
}
