/*
 * 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.sling.crankstart.launcher;

import java.io.Closeable;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.sling.provisioning.model.Model;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** Setup the OSGi framework based on a provisioning model */
@SuppressWarnings("serial")
public class FrameworkSetup extends HashMap<String, Object> implements Callable<Object> {
    private final Logger log = LoggerFactory.getLogger(getClass());
    
    @SuppressWarnings("unchecked")
    private <T> T require(String key, Class<T> desiredType) throws IllegalStateException {
        final Object o = get(key);
        if(o == null) {
            throw new IllegalStateException("Missing required object:" + key);
        }
        if(!o.getClass().isAssignableFrom(desiredType)) {
            throw new ClassCastException("Object '" + key + "' is not a " + desiredType.getName());
        }
        return (T)o;
    }
    
    public Object call() throws Exception {
        final Model model = require(Launcher.MODEL_KEY, Model.class);
        
        log.info("Setting OSGi framework properties");
        final Map<String, String> fprops = new FrameworkProperties(model).getProperties(Launcher.ONLY_CRANKSTART_FILTER);
                
        log.info("Starting the OSGi framework");
        final FrameworkFactory factory = (FrameworkFactory)getClass().getClassLoader().loadClass("org.apache.felix.framework.FrameworkFactory").newInstance();
        final Framework framework = factory.newFramework(fprops);
        framework.start();
        final Configurations cfg = new Configurations(framework.getBundleContext(), model);
        setShutdownHook(framework, new Closeable[] { cfg });
        log.info("OSGi framework started");
        
        log.info("Installing bundles from provisioning model");
        final BundlesInstaller bi = new BundlesInstaller(model);
        final BundleContext bc = framework.getBundleContext();
        bi.installBundles(bc, Launcher.NOT_CRANKSTART_FILTER);
        cfg.maybeConfigure();
        
        // TODO shall we gradually increase start levels like the launchpad does?? Reuse that code?
        final Bundle [] bundles = bc.getBundles();
        log.info("Starting all bundles ({} bundles installed)", bundles.length);
        int started = 0;
        int failed = 0;
        for(Bundle b : bundles) {
            try {
                b.start();
                started++;
            } catch(BundleException be) {
                failed++;
                log.warn("Error starting bundle " + b.getSymbolicName(), be);
            }
            cfg.maybeConfigure();
        }
        log.info("{} bundles started, {} failed to start, total {}", started, failed, bundles.length);
        
        log.info("OSGi setup done, waiting for framework to stop");
        framework.waitForStop(0);
        
        return null;
    }
    
    private void setShutdownHook(final Framework osgiFramework, final Closeable ... toClose) {
        // Shutdown the framework when the JVM exits
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                if(osgiFramework != null && osgiFramework.getState() == Bundle.ACTIVE) {
                    try {
                        log.info("Stopping the OSGi framework");
                        osgiFramework.stop();
                        log.info("Waiting for the OSGi framework to exit");
                        osgiFramework.waitForStop(0);
                        log.info("OSGi framework stopped");
                    } catch(Exception e) {
                        log.error("Exception while stopping OSGi framework", e);
                    } finally {
                        for(Closeable c : toClose) {
                            try {
                                c.close();
                            } catch(IOException ignore) {
                            }
                        }
                    }
                }
            }
        });
    }
}