//
//  ========================================================================
//  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.Dictionary;
import java.util.HashMap;

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.utils.BundleFileLocatorHelperFactory;
import org.eclipse.jetty.osgi.boot.utils.OSGiClassLoader;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
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.xml.XmlConfiguration;
import org.osgi.framework.Bundle;




/**
 * AbstractContextProvider
 *
 * Base class for DeploymentManager Providers that can deploy ContextHandlers into 
 * Jetty that have been discovered via OSGI either as bundles or services.
 * 
 */
public abstract class AbstractContextProvider extends AbstractLifeCycle implements AppProvider
{
    private static final Logger LOG = Log.getLogger(AbstractContextProvider.class);
    
    private DeploymentManager _deploymentManager;    
    
    private ServerInstanceWrapper _serverWrapper;
    
    
    
    
    /* ------------------------------------------------------------ */
    /**
     * OSGiApp
     *
     *
     */
    public class OSGiApp extends AbstractOSGiApp
    {
        private String _contextFile;
        private ContextHandler _contextHandler;
        private boolean _configured = false;
        
        public OSGiApp(DeploymentManager manager, AppProvider provider, String originId, Bundle bundle, String contextFile)
        {
            super(manager, provider, bundle, originId);
            _contextFile = contextFile;
        }
        
        public OSGiApp(DeploymentManager manager, AppProvider provider, Bundle bundle, Dictionary properties, String contextFile, String originId)
        {
            super(manager, provider, bundle, properties, originId);
            _contextFile = contextFile;
        }
               
        public String getContextFile ()
        {
            return _contextFile;
        }
        
        public void setHandler(ContextHandler h)
        {
            _contextHandler = h;
        }
       
        public ContextHandler createContextHandler()
        throws Exception
        {
            configureContextHandler();
            return _contextHandler;
        }

        public void configureContextHandler()
        throws Exception
        {
            if (_configured)
                return;

            _configured = true;
            
            //Override for bundle root may have been set
            String bundleOverrideLocation = (String)_properties.get(OSGiWebappConstants.JETTY_BUNDLE_INSTALL_LOCATION_OVERRIDE);
            if (bundleOverrideLocation == null)
                bundleOverrideLocation = (String)_properties.get(OSGiWebappConstants.SERVICE_PROP_BUNDLE_INSTALL_LOCATION_OVERRIDE);

            //Location on filesystem of bundle or the bundle override location
            File bundleLocation = BundleFileLocatorHelperFactory.getFactory().getHelper().getBundleInstallLocation(_bundle);
            File root = (bundleOverrideLocation==null?bundleLocation:new File(bundleOverrideLocation));
            Resource rootResource = Resource.newResource(BundleFileLocatorHelperFactory.getFactory().getHelper().getLocalURL(root.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;
            }
            
            //Set the base resource of the ContextHandler, if not already set, can also be overridden by the context xml file
            if (_contextHandler != null && _contextHandler.getBaseResource() == null)
            {
                _contextHandler.setBaseResource(rootResource);
            }

            //Use a classloader that knows about the common jetty parent loader, and also the bundle                  
            OSGiClassLoader classLoader = new OSGiClassLoader(getServerInstanceWrapper().getParentClassLoaderForWebapps(), _bundle);

            //if there is a context file, find it and apply it
            if (_contextFile == null && _contextHandler == null)
                throw new IllegalStateException("No context file or ContextHandler");

            if (_contextFile != null)
            {   
                //apply the contextFile, creating the ContextHandler, the DeploymentManager will register it in the ContextHandlerCollection
                Resource res = null;
                
                String jettyHome = (String)getServerInstanceWrapper().getServer().getAttribute(OSGiServerConstants.JETTY_HOME);
                if (jettyHome == null)
                    jettyHome =  System.getProperty(OSGiServerConstants.JETTY_HOME);
                
                res = findFile(_contextFile, jettyHome, bundleOverrideLocation, _bundle);

                //apply the context xml file, either to an existing ContextHandler, or letting the
                //it create the ContextHandler as necessary
                if (res != null)
                { 
                    ClassLoader cl = Thread.currentThread().getContextClassLoader();

                    LOG.debug("Context classloader = " + cl);
                    try
                    {
                        Thread.currentThread().setContextClassLoader(classLoader);
                        
                        XmlConfiguration xmlConfiguration = new XmlConfiguration(res.getInputStream());
                        HashMap properties = new HashMap();
                        //put the server instance in
                        properties.put("Server", getServerInstanceWrapper().getServer());
                        //put in the location of the bundle root
                        properties.put(OSGiWebappConstants.JETTY_BUNDLE_ROOT, rootResource.toString());
                        
                        // insert the bundle's location as a property.
                        xmlConfiguration.getProperties().putAll(properties);

                        if (_contextHandler == null)
                            _contextHandler = (ContextHandler) xmlConfiguration.configure();
                        else
                            xmlConfiguration.configure(_contextHandler);
                    }
                    finally
                    {
                        Thread.currentThread().setContextClassLoader(cl);
                    }
                }
            }

            //Set up the class loader we created
            _contextHandler.setClassLoader(classLoader);
            
            
            //If a bundle/service property specifies context path, let it override the context xml
            String contextPath = (String)_properties.get(OSGiWebappConstants.RFC66_WEB_CONTEXTPATH);
            if (contextPath == null)
                contextPath = (String)_properties.get(OSGiWebappConstants.SERVICE_PROP_CONTEXT_PATH);
            if (contextPath != null)
                _contextHandler.setContextPath(contextPath);    
            
            //osgi Enterprise Spec r4 p.427
            _contextHandler.setAttribute(OSGiWebappConstants.OSGI_BUNDLECONTEXT, _bundle.getBundleContext());
            
            //make sure we protect also the osgi dirs specified by OSGi Enterprise spec
            String[] targets = _contextHandler.getProtectedTargets();
            int length = (targets==null?0:targets.length);
            
            String[] updatedTargets = null;
            if (targets != null)
            {
                updatedTargets = new String[length+OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length];
                System.arraycopy(targets, 0, updatedTargets, 0, length);
                
            }
            else
                updatedTargets = new String[OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length];
            System.arraycopy(OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS, 0, updatedTargets, length, OSGiWebappConstants.DEFAULT_PROTECTED_OSGI_TARGETS.length);
            _contextHandler.setProtectedTargets(updatedTargets);
           
        }

    }
    
    /* ------------------------------------------------------------ */
    public AbstractContextProvider(ServerInstanceWrapper wrapper)
    {
        _serverWrapper = wrapper;
    }
    
    
    /* ------------------------------------------------------------ */
    public ServerInstanceWrapper getServerInstanceWrapper()
    {
        return _serverWrapper;
    }
    
    /* ------------------------------------------------------------ */
    /** 
     * @see org.eclipse.jetty.deploy.AppProvider#createContextHandler(org.eclipse.jetty.deploy.App)
     */
    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 ContextHandler suitable to deploy in OSGi
        ContextHandler h = ((OSGiApp)app).createContextHandler();           
        return h;
    }
    
    /* ------------------------------------------------------------ */
    public void setDeploymentManager(DeploymentManager deploymentManager)
    {
        _deploymentManager = deploymentManager;
    }
    
    /* ------------------------------------------------------------ */
    public DeploymentManager getDeploymentManager()
    {
        return _deploymentManager;
    }
}
