/* 
 * 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.felix.ipojo.composite;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Dictionary;
import java.util.List;
import java.util.Properties;

import org.apache.felix.ipojo.ComponentInstance;
import org.apache.felix.ipojo.Factory;
import org.apache.felix.ipojo.IPojoContext;
import org.apache.felix.ipojo.ServiceContext;
import org.apache.felix.ipojo.context.ServiceReferenceImpl;
import org.apache.felix.ipojo.context.ServiceRegistry;
import org.apache.felix.ipojo.util.Tracker;
import org.apache.felix.ipojo.util.TrackerCustomizer;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;

/**
 * CompositeServiceContext Class. This class provides an implementation of the
 * service context for composite.
 * 
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class CompositeServiceContext implements ServiceContext, TrackerCustomizer {

    /**
     * Structure storing the reference, the factory and the registration.
     */
    private class Record {
        /**
         * Reference of the represented factory from the external context.
         */
        private ServiceReference m_ref;
        /**
         * Registration of the factory in the internal context.
         */
        private ServiceRegistration m_reg;
        /**
         * Represented Factory. 
         */
        private FactoryProxy m_fact;
    }

    /**
     * List of imported factories.
     */
    private List m_factories = new ArrayList();
    /**
     * Internal service registry.
     */
    private ServiceRegistry m_registry;

    /**
     * Component Instance who creates this registry.
     */
    private ComponentInstance m_instance;
    
    /**
     * Global service context.
     */
    private BundleContext m_global;
    
    /**
     * Tracker tracking Factories to import.
     */
    private Tracker m_tracker;

    /**
     * Constructor. This constructor instantiate a service registry with the
     * given bundle context.
     * 
     * @param context : the bundle context
     */
    public CompositeServiceContext(BundleContext context) {
        m_registry = new ServiceRegistry(context);
        if (context instanceof IPojoContext) {
            m_global = ((IPojoContext) context).getGlobalContext();
        } else {
            m_global = context; // the parent context is the global context
        }
    }

    /**
     * Constructor.
     * 
     * @param context : the bundle context
     * @param instance : the component instance owning this context
     */
    public CompositeServiceContext(BundleContext context, ComponentInstance instance) {
        this(context);
        m_instance = instance;
    }

    /**
     * Add a service listener.
     * @param arg0 : The service listener to add
     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener)
     */
    public void addServiceListener(ServiceListener arg0) {
        m_registry.addServiceListener(arg0);
    }

    /**
     * Add a filtered service listener.
     * @param arg0 : the service listener object to add
     * @param arg1 : the LDAP filter for this listener
     * @throws InvalidSyntaxException : occurs if the LDAP filter is malformed
     * @see org.apache.felix.ipojo.ServiceContext#addServiceListener(org.osgi.framework.ServiceListener,
     * java.lang.String)
     */
    public void addServiceListener(ServiceListener arg0, String arg1) throws InvalidSyntaxException {
        m_registry.addServiceListener(arg0, arg1);
    }

    /**
     * Get all service references.
     * @param arg0 : The required service interface.
     * @param arg1 : LDAP filter
     * @return the list of all service reference matching with the query
     * @throws InvalidSyntaxException : occurs when the given filter is malformed
     * @see org.apache.felix.ipojo.ServiceContext#getAllServiceReferences(java.lang.String,
     * java.lang.String)
     */
    public ServiceReference[] getAllServiceReferences(String arg0, String arg1) throws InvalidSyntaxException {
        return m_registry.getAllServiceReferences(arg0, arg1);
    }

    /**
     * Get a service object for the given service reference.
     * @param arg0 : the service reference
     * @return the service object or null if the reference is no more valid or if the object is not accessible
     * @see org.apache.felix.ipojo.ServiceContext#getService(org.osgi.framework.ServiceReference)
     */
    public Object getService(ServiceReference arg0) {
        if (arg0 instanceof ServiceReferenceImpl) {
            return m_registry.getService(m_instance, arg0);
        } else {
            throw new RuntimeException("Cannot get a global service from the local registry");
        }
    }

    
    /**
     * Get a service reference for the required interface.
     * @param arg0 : the required interface name
     * @return the service reference or null if no available provider
     * @see org.apache.felix.ipojo.ServiceContext#getServiceReference(java.lang.String)
     */
    public ServiceReference getServiceReference(String arg0) {
        return m_registry.getServiceReference(arg0);
    }

    /**
     * Get all accessible service reference for the given query.
     * @param clazz : required interface
     * @param filter : LDAP filter
     * @return the list (array) of service reference matching with the query.
     * @throws InvalidSyntaxException : occurs when the LDAP filter is malformed
     * @see org.apache.felix.ipojo.ServiceContext#getServiceReferences(java.lang.String, java.lang.String)
     */
    public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException {
        return m_registry.getServiceReferences(clazz, filter);
    }


    /**
     * Register a service inside the composite context.
     * @param arg0 : list of interfaces to register.
     * @param arg1 : service object
     * @param arg2 : properties list
     * @return the service registration
     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
     */
    public ServiceRegistration registerService(String[] arg0, Object arg1, Dictionary arg2) {
        return m_registry.registerService(m_instance, arg0, arg1, arg2);
    }

    /**
     * Register a service inside the composite context.
     * @param arg0 : interface to register.
     * @param arg1 : service object
     * @param arg2 : properties list
     * @return the service registration
     * @see org.apache.felix.ipojo.ServiceContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
     */
    public ServiceRegistration registerService(String arg0, Object arg1, Dictionary arg2) {
        return m_registry.registerService(m_instance, arg0, arg1, arg2);
    }

    /**
     * Remove a service listener.
     * @param arg0 : the service listener to remove
     * @see org.apache.felix.ipojo.ServiceContext#removeServiceListener(org.osgi.framework.ServiceListener)
     */
    public void removeServiceListener(ServiceListener arg0) {
        m_registry.removeServiceListener(arg0);
    }

    /**
     * Unget a service.
     * @param arg0 the service reference to unget
     * @return true
     * @see org.apache.felix.ipojo.ServiceContext#ungetService(org.osgi.framework.ServiceReference)
     */
    public boolean ungetService(ServiceReference arg0) {
        return m_registry.ungetService(m_instance, arg0);
    }

    /**
     * Import a factory form the parent to the internal registry.
     * 
     * @param ref : the reference of the factory to import.
     */
    private void importFactory(ServiceReference ref) {        
        Record rec = new Record();
        m_factories.add(rec);
        Dictionary dict = new Properties();
        for (int j = 0; j < ref.getPropertyKeys().length; j++) {
            dict.put(ref.getPropertyKeys()[j], ref.getProperty(ref.getPropertyKeys()[j]));
        }
        rec.m_fact = new FactoryProxy((Factory) m_tracker.getService(ref), this);
        rec.m_reg = registerService(Factory.class.getName(), rec.m_fact, dict);
        rec.m_ref = ref;
    }

    /**
     * Remove a factory of the available factory list.
     * 
     * @param ref : the reference on the factory to remove.
     */
    private void removeFactory(ServiceReference ref) {
        for (int i = 0; i < m_factories.size(); i++) {
            Record rec = (Record) m_factories.get(i);
            if (rec.m_ref == ref) {
                if (rec.m_reg != null) {
                    rec.m_reg.unregister();
                    rec.m_fact = null;
                }
                m_tracker.ungetService(rec.m_ref);
                m_factories.remove(rec);
                return;
            }
        }
    }

    /**
     * Start the registry management.
     */
    public void start() {
        m_tracker = new Tracker(m_global, Factory.class.getName(), this);
        m_tracker.open();
    }

    /**
     * Stop the registry management.
     */
    public synchronized void stop() {
        m_tracker.close();
        m_registry.reset();
        for (int i = 0; i < m_factories.size(); i++) {
            Record rec = (Record) m_factories.get(i);
            removeFactory(rec.m_ref);
        }
        m_tracker = null;
    }

    /**
     * Check if the factory list contain the given reference.
     * 
     * @param ref : the reference to find.
     * @return true if the list contains the given reference.
     */
    private boolean containsRef(ServiceReference ref) {
        for (int i = 0; i < m_factories.size(); i++) {
            Record rec = (Record) m_factories.get(i);
            if (rec.m_ref == ref) {
                return true;
            }
        }
        return false;
    }

    /**
     * Add a bundle listener.
     * Delegate on the global bundle context.
     * @param arg0 : bundle listener to add
     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
     */
    public void addBundleListener(BundleListener arg0) {
        m_global.addBundleListener(arg0);
    }

    /**
     * Add a framework listener.
     * Delegate on the global bundle context.
     * @param arg0 : framework listener to add.
     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
     */
    public void addFrameworkListener(FrameworkListener arg0) {
        m_global.addFrameworkListener(arg0);
    }

    /**
     * Create a LDAP filter.
     * @param arg0 : String-form of the filter
     * @return the created filter object
     * @throws InvalidSyntaxException : if the given argument is not a valid against the LDAP grammar.
     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
     */
    public Filter createFilter(String arg0) throws InvalidSyntaxException {
        return m_global.createFilter(arg0);
    }

    /**
     * Get the current bundle.
     * @return the current bundle
     * @see org.osgi.framework.BundleContext#getBundle()
     */
    public Bundle getBundle() {
        return m_global.getBundle();
    }

    /**
     * Get the bundle object with the given id.
     * @param bundleId : bundle id
     * @return the bundle object
     * @see org.osgi.framework.BundleContext#getBundle(long)
     */
    public Bundle getBundle(long bundleId) {
        return m_global.getBundle(bundleId);
    }

    /**
     * Get installed bundles.
     * @return the list of installed bundles
     * @see org.osgi.framework.BundleContext#getBundles()
     */
    public Bundle[] getBundles() {
        return m_global.getBundles();
    }


    /**
     * Get a data file.
     * @param filename : File name.
     * @return the File object
     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
     */
    public File getDataFile(String filename) {
        return m_global.getDataFile(filename);
    }

    /**
     * Get a property value.
     * @param key : key of the asked property
     * @return the property value (object) or null if no property are associated with the given key
     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
     */
    public String getProperty(String key) {
        return m_global.getProperty(key);
    }

    /**
     * Install a bundle.
     * @param location : URL of the bundle to install
     * @return the installed bundle
     * @throws BundleException : if the bundle cannot be installed correctly
     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
     */
    public Bundle installBundle(String location) throws BundleException {
        return m_global.installBundle(location);
    }

    /**
     * Install a bundle.
     * @param location : URL of the bundle to install
     * @param input : 
     * @return the installed bundle
     * @throws BundleException : if the bundle cannot be installed correctly
     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
     */
    public Bundle installBundle(String location, InputStream input) throws BundleException {
        return m_global.installBundle(location, input);
    }

    /**
     * Remove a bundle listener.
     * @param listener : the listener to remove
     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
     */
    public void removeBundleListener(BundleListener listener) {
        m_global.removeBundleListener(listener);
    }

    /**
     * Remove a framework listener.
     * @param listener : the listener to remove
     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
     */
    public void removeFrameworkListener(FrameworkListener listener) {
        m_global.removeFrameworkListener(listener);
    }

    /**
     * A new factory is detected.
     * @param reference : service reference
     * @return true if not already imported.
     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addingService(org.osgi.framework.ServiceReference)
     */
    public boolean addingService(ServiceReference reference) {
        if (!containsRef(reference)) {
            return true;
        }
        return false;
    }
    
    /**
     * A matching reference has been added. The import factory can now be imported.
     * @param reference : the added reference.
     * @see org.apache.felix.ipojo.util.TrackerCustomizer#addedService(org.osgi.framework.ServiceReference)
     */
    public void addedService(ServiceReference reference) {
        importFactory(reference);
    }

    /**
     * An imported factory is modified.
     * @param reference : modified reference
     * @param service : factory object.
     * @see org.apache.felix.ipojo.util.TrackerCustomizer#modifiedService(org.osgi.framework.ServiceReference, java.lang.Object)
     */
    public void modifiedService(ServiceReference reference, Object service) {
        for (int i = 0; i < m_factories.size(); i++) {
            Record rec = (Record) m_factories.get(i);
            if (rec.m_ref == reference) {
                Dictionary dict = new Properties();
                for (int j = 0; j < reference.getPropertyKeys().length; j++) {
                    dict.put(reference.getPropertyKeys()[j], reference.getProperty(reference.getPropertyKeys()[j]));
                }
                rec.m_reg.setProperties(dict);
                return;
            }
        }
    }

    /**
     * An imported factory disappears.
     * @param reference : reference
     * @param service : factory object.
     * @see org.apache.felix.ipojo.util.TrackerCustomizer#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
     */
    public void removedService(ServiceReference reference, Object service) {
        if (containsRef(reference)) {
            removeFactory(reference);
        }
        
    }
}
