/**
 * 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.camel.osgi;

import java.io.BufferedInputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.camel.CamelContext;
import org.apache.camel.Component;
import org.apache.camel.spi.ComponentResolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.SynchronousBundleListener;
import org.springframework.osgi.internal.context.support.BundleDelegatingClassLoader;

/**
 * Created by IntelliJ IDEA.
 * User: gnodet
 * Date: Sep 20, 2007
 * Time: 10:37:31 AM
 * To change this template use File | Settings | File Templates.
 */
public class OsgiComponentResolver implements ComponentResolver {

    private static final transient Log LOG = LogFactory.getLog(OsgiComponentResolver.class);

    private BundleContext bundleContext;
    private Map<String, ComponentEntry> components;

    private class BundleListener implements SynchronousBundleListener {
        public void bundleChanged(BundleEvent event) {
            try {
                Bundle bundle = event.getBundle();
                if (event.getType() == BundleEvent.RESOLVED) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Bundle resolved: " + bundle.getSymbolicName());
                    }
                    mayBeAddComponentFor(bundle);
                } else if (event.getType() == BundleEvent.UNRESOLVED) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Bundle unresolved: " + bundle.getSymbolicName());
                    }
                    mayBeRemoveComponentFor(bundle);
                }
            } catch (Throwable e) {
                LOG.fatal("Exception handing bundle changed event", e);
            }
        }
    }

    private class ComponentEntry {
        Bundle bundle;
        String path;
        String name;
        Class  type;
    }

    public OsgiComponentResolver(BundleContext bundleContext) {
        this.bundleContext = bundleContext;
    }

    protected void init() {
        if (components != null) {
            return;
        }
        LOG.debug("Initializing OsgiComponentResolver");
        components = new HashMap<String, ComponentEntry>();
        bundleContext.addBundleListener(new BundleListener());
        Bundle[] previousBundles = bundleContext.getBundles();
        for (int i = 0; i < previousBundles.length; i++) {
            int state = previousBundles[i].getState();
            if (state == Bundle.RESOLVED || state == Bundle.ACTIVE) {
            	try {
            		mayBeAddComponentFor(previousBundles[i]);
            	} catch (Exception e) {
            		LOG.error("Component " + previousBundles[i] + " not added due to " + e.toString(), e);
            	}
            }
        }
    }

    protected synchronized void mayBeAddComponentFor(Bundle bundle) {
        Enumeration e = bundle.getEntryPaths("/META-INF/services/org/apache/camel/component/");
        if (e != null) {
            while (e.hasMoreElements()) {
                String path = (String) e.nextElement();
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Found entry: " + path + " in bundle " + bundle.getSymbolicName());
                }
                ComponentEntry entry = new ComponentEntry();
                entry.bundle = bundle;
                entry.path = path;
                entry.name = path.substring(path.lastIndexOf("/") + 1);
                components.put(entry.name, entry);
            }
        }
    }

    protected synchronized void mayBeRemoveComponentFor(Bundle bundle) {
        for (ComponentEntry entry : components.values()) {
            if (entry.bundle == bundle) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Removing entry: " + entry.path + " in bundle " + bundle.getSymbolicName());
                }
                components.remove(entry.name);
            }
        }
    }

    protected synchronized Class getComponent(String name) throws Exception {
        ComponentEntry entry = components.get(name);
        if (entry == null) {
            return null;
        }
        if (entry.type == null) {
            URL url = entry.bundle.getEntry(entry.path);
            // lets load the file
            Properties properties = new Properties();
            BufferedInputStream reader = null;
            try {
                reader = new BufferedInputStream(url.openStream());
                properties.load(reader);
            } finally {
                try {
                    reader.close();
                } catch (Exception ignore) {
                }
            }
            String classname = (String) properties.get("class");
            ClassLoader loader = BundleDelegatingClassLoader.createBundleClassLoaderFor(entry.bundle);
            entry.type = loader.loadClass(classname);
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("Found component: " + name + " via type: " + entry.type.getName());
        }
        return entry.type;
    }

    public Component resolveComponent(String name, CamelContext context) throws Exception {
        Object bean = null;
        try {
            bean = context.getRegistry().lookup(name);
            if (bean != null && LOG.isDebugEnabled()) {
                LOG.debug("Found component: " + name + " in registry: " + bean);
            }
        }
        catch (Exception e) {
            LOG.debug("Ignored error looking up bean: " + name + ". Error: " + e);
        }
        if (bean != null) {
            if (bean instanceof Component) {
                return (Component) bean;
            }
            else {
                throw new IllegalArgumentException("Bean with name: " + name + " in registry is not a Component: " + bean);
            }
        }
        // Check in OSGi bundles
        init();
        Class type = null;
        try {
            type = getComponent(name);
        }
        catch (Throwable e) {
            throw new IllegalArgumentException("Invalid URI, no Component registered for scheme : " + name, e);
        }
        if (type == null) {
            return null;
        }
        if (Component.class.isAssignableFrom(type)) {
            return (Component) context.getInjector().newInstance(type);
        } else {
            throw new IllegalArgumentException("Type is not a Component implementation. Found: " + type.getName());
        }
    }

}
