/*
 * 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.launchpad.base.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Properties;

import org.apache.felix.framework.Felix;
import org.apache.sling.launchpad.base.shared.Loader;
import org.apache.sling.launchpad.base.shared.Notifiable;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkEvent;


public class SlingFelix extends Felix {

    private final Notifiable notifiable;

    private Thread notifierThread;

    // see getBundle(Class) below
    private Method getBundleMethod;

    public SlingFelix(final Notifiable notifiable, @SuppressWarnings("rawtypes") final Map props) throws Exception {
        super(props);
        this.notifiable = notifiable;
    }

    @Override
    public void update() throws BundleException {
        update(null);
    }

    @Override
    public void update(final InputStream is) throws BundleException {
        // get the update file and make sure, the stream is closed
        try {
            startNotifier(true, is);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException ignore) {
                }
            }
        }

        // just stop the framework now
        super.stop();
    }

    public void restart() throws BundleException {
        super.stop();
    }

    @Override
    public void stop() throws BundleException {
        startNotifier(false, null);
        super.stop();
    }

    @Override
    public void stop(final int status) throws BundleException {
        startNotifier(false, null);
        super.stop(status);
    }

    private synchronized void startNotifier(final boolean restart, final InputStream ins) {
        if (notifierThread == null) {
            notifierThread = new Thread(new Notifier(restart, ins),
                "Sling Notifier");
            notifierThread.setDaemon(false);
            notifierThread.start();
        }
    }

    /**
     * Returns the bundle from which the given class has been loaded or
     * <code>null</code> if the class has not been loaded through any
     * of the bundles in this framework.
     * <p>
     * This method delegates to Felix.getBundle(Class) to support the
     * URLHandlers service implementation. See SLING-2554 for details.
     *
     * @param clazz The class to check
     *
     * @return The Bundle or <code>null</code> if the class has not been
     *      loaded through any of the bundles in this framework.
     */
    public Bundle getBundle(Class<?> clazz) {
        Method getBundleMethod = this.getBundleMethod;
        if (getBundleMethod == null) {
            Class<?> provider = Felix.class; // super class actually
            try {
                getBundleMethod = provider.getDeclaredMethod("getBundle", Class.class);
                getBundleMethod.setAccessible(true);
                this.getBundleMethod = getBundleMethod;
            } catch (Exception e) {
                throw new NoSuchMethodError("getBundle");
            }
        }

        try {
            return (Bundle) getBundleMethod.invoke(this, clazz);
        } catch (IllegalArgumentException e) {
            // we don't expect this, we checked everything
        } catch (IllegalAccessException e) {
            // we don't expect this, because we set the method accessible
        } catch (InvocationTargetException e) {
            // unpack and rethrow
            Throwable t = e.getCause();
            if (t instanceof RuntimeException) {
                throw (RuntimeException) t;
            }
        }

        return null;
    }

    private class Notifier implements Runnable {

        private final boolean restart;

        private final File updateFile;

        private Notifier(final boolean restart, final InputStream ins) {
            this.restart = restart;

            if (ins != null) {
                File tmpFile;
                try {
                    tmpFile = File.createTempFile("slingupdate", ".jar");
                    Loader.spool(ins, tmpFile);
                } catch (IOException ioe) {
                    // TOOD: log
                    tmpFile = null;
                }
                this.updateFile = tmpFile;
            } else {
                this.updateFile = null;
            }
        }

        @Override
        public void run() {
            boolean restart = this.restart;
            try {
                if (SlingFelix.this.waitForStop(0).getType() == FrameworkEvent.STOPPED_SYSTEM_REFRESHED) {
                    restart = true;
                }
            } catch (InterruptedException ie) {
                Thread.currentThread().interrupt();
            }

            if (restart) {
                SlingFelix.this.notifiable.updated(updateFile);
            } else {
                SlingFelix.this.notifiable.stopped();
            }
        }
    }
}
