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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.LoggingLevel;
import org.apache.camel.NoTypeConversionAvailableException;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.TypeConverter;
import org.apache.camel.TypeConverterExists;
import org.apache.camel.TypeConverters;
import org.apache.camel.impl.DefaultPackageScanClassResolver;
import org.apache.camel.impl.converter.DefaultTypeConverter;
import org.apache.camel.spi.FactoryFinder;
import org.apache.camel.spi.Injector;
import org.apache.camel.spi.TypeConverterLoader;
import org.apache.camel.spi.TypeConverterRegistry;
import org.apache.camel.support.service.ServiceHelper;
import org.apache.camel.support.service.ServiceSupport;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class OsgiTypeConverter extends ServiceSupport implements TypeConverter, TypeConverterRegistry,
    ServiceTrackerCustomizer<TypeConverterLoader, Object> {
    private static final Logger LOG = LoggerFactory.getLogger(OsgiTypeConverter.class);

    private final BundleContext bundleContext;
    private final CamelContext camelContext;
    private final Injector injector;
    private final FactoryFinder factoryFinder;
    private final ServiceTracker<TypeConverterLoader, Object> tracker;
    private volatile DefaultTypeConverter delegate;

    public OsgiTypeConverter(BundleContext bundleContext, CamelContext camelContext, Injector injector, FactoryFinder factoryFinder) {
        this.bundleContext = bundleContext;
        this.camelContext = camelContext;
        this.injector = injector;
        this.factoryFinder = factoryFinder;
        this.tracker = new ServiceTracker<>(bundleContext, TypeConverterLoader.class.getName(), this);
    }

    public Object addingService(ServiceReference<TypeConverterLoader> serviceReference) {
        LOG.trace("AddingService: {}, Bundle: {}", serviceReference, serviceReference.getBundle());        
        TypeConverterLoader loader = bundleContext.getService(serviceReference);
        try {
            LOG.debug("loading type converter from bundle: {}", serviceReference.getBundle().getSymbolicName());
            if (delegate != null) {
                loader.load(delegate);
            }
        } catch (Throwable t) {
            throw new RuntimeCamelException("Error loading type converters from service: " + serviceReference + " due: " + t.getMessage(), t);
        }
       
        return loader;
    }

    public void modifiedService(ServiceReference<TypeConverterLoader> serviceReference, Object o) {
    }

    public void removedService(ServiceReference<TypeConverterLoader> serviceReference, Object o) {
        LOG.trace("RemovedService: {}, Bundle: {}", serviceReference, serviceReference.getBundle());  
        try {
            ServiceHelper.stopService(this.delegate);
        } catch (Exception e) {
            // ignore
            LOG.debug("Error stopping service due: " + e.getMessage() + ". This exception will be ignored.", e);
        }
        // It can force camel to reload the type converter again
        this.delegate = null;
        
        // TODO: reloading all type converters when one service is removed is suboptimal...
    }

    @Override
    protected void doStart() throws Exception {
        this.tracker.open();
    }

    @Override
    protected void doStop() throws Exception {
        this.tracker.close();
        ServiceHelper.stopService(this.delegate);
        this.delegate = null;
    }

    public boolean allowNull() {
        return getDelegate().allowNull();
    }

    public <T> T convertTo(Class<T> type, Object value) {
        return getDelegate().convertTo(type, value);
    }

    public <T> T convertTo(Class<T> type, Exchange exchange, Object value) {
        return getDelegate().convertTo(type, exchange, value);
    }

    public <T> T mandatoryConvertTo(Class<T> type, Object value) throws NoTypeConversionAvailableException {
        return getDelegate().mandatoryConvertTo(type, value);
    }

    public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) throws NoTypeConversionAvailableException {
        return getDelegate().mandatoryConvertTo(type, exchange, value);
    }

    public <T> T tryConvertTo(Class<T> type, Exchange exchange, Object value) {
        return getDelegate().tryConvertTo(type, exchange, value);
    }

    public <T> T tryConvertTo(Class<T> type, Object value) {
        return getDelegate().tryConvertTo(type, value);
    }

    public void addTypeConverter(Class<?> toType, Class<?> fromType, TypeConverter typeConverter) {
        getDelegate().addTypeConverter(toType, fromType, typeConverter);
    }

    public void addTypeConverters(TypeConverters typeConverters) {
        getDelegate().addTypeConverters(typeConverters);
    }

    public boolean removeTypeConverter(Class<?> toType, Class<?> fromType) {
        return getDelegate().removeTypeConverter(toType, fromType);
    }

    public void addFallbackTypeConverter(TypeConverter typeConverter, boolean canPromote) {
        getDelegate().addFallbackTypeConverter(typeConverter, canPromote);
    }

    public TypeConverter lookup(Class<?> toType, Class<?> fromType) {
        return getDelegate().lookup(toType, fromType);
    }

    public List<Class<?>[]> listAllTypeConvertersFromTo() {
        return getDelegate().listAllTypeConvertersFromTo();
    }

    public void setInjector(Injector injector) {
        getDelegate().setInjector(injector);
    }

    public Injector getInjector() {
        return getDelegate().getInjector();
    }

    public Statistics getStatistics() {
        return getDelegate().getStatistics();
    }

    public int size() {
        return getDelegate().size();
    }

    public LoggingLevel getTypeConverterExistsLoggingLevel() {
        return getDelegate().getTypeConverterExistsLoggingLevel();
    }

    public void setTypeConverterExistsLoggingLevel(LoggingLevel loggingLevel) {
        getDelegate().setTypeConverterExistsLoggingLevel(loggingLevel);
    }

    public TypeConverterExists getTypeConverterExists() {
        return getDelegate().getTypeConverterExists();
    }

    public void setTypeConverterExists(TypeConverterExists typeConverterExists) {
        getDelegate().setTypeConverterExists(typeConverterExists);
    }

    public synchronized DefaultTypeConverter getDelegate() {
        if (delegate == null) {
            delegate = createRegistry();
        }
        return delegate;
    }

    protected DefaultTypeConverter createRegistry() {
        // base the osgi type converter on the default type converter
        DefaultTypeConverter answer = new DefaultTypeConverter(new DefaultPackageScanClassResolver() {
            @Override
            public Set<ClassLoader> getClassLoaders() {
                // we don't need any classloaders as we use OSGi service tracker instead
                return Collections.emptySet();
            }
        }, injector, factoryFinder, false);

        // inject CamelContext
        answer.setCamelContext(camelContext);

        try {
            // only load the core type converters, as OSGi activator will keep track on bundles
            // being installed/uninstalled and load type converters as part of that process
            answer.loadCoreTypeConverters();
        } catch (Exception e) {
            throw new RuntimeCamelException("Error loading CoreTypeConverter due: " + e.getMessage(), e);
        }

        // Load the type converters the tracker has been tracking
        // Here we need to use the ServiceReference to check the ranking
        ServiceReference<TypeConverterLoader>[] serviceReferences = this.tracker.getServiceReferences();
        if (serviceReferences != null) {
            ArrayList<ServiceReference<TypeConverterLoader>> servicesList = 
                new ArrayList<>(Arrays.asList(serviceReferences));
            // Just make sure we install the high ranking fallback converter at last
            Collections.sort(servicesList);
            for (ServiceReference<TypeConverterLoader> sr : servicesList) {
                try {
                    LOG.debug("loading type converter from bundle: {}", sr.getBundle().getSymbolicName());
                    ((TypeConverterLoader)this.tracker.getService(sr)).load(answer);
                } catch (Throwable t) {
                    throw new RuntimeCamelException("Error loading type converters from service: " + sr + " due: " + t.getMessage(), t);
                }
            }
        }

        LOG.trace("Created TypeConverter: {}", answer);
        return answer;
    }
}
