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


import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceObjects;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;


/**
 * The <code>MockBundleContext</code> TODO
 *
 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
 */
public class MockBundleContext implements BundleContext
{

    private Bundle theBundle;
    private Map services;

    private Set serviceListeners;


    public MockBundleContext( long bundleId, String bundleSymbolicName )
    {
        theBundle = new MockBundle( this, bundleId, bundleSymbolicName );
        services = new HashMap();
        serviceListeners = new HashSet();
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#addBundleListener(org.osgi.framework.BundleListener)
     */
    @Override
    public void addBundleListener( BundleListener arg0 )
    {
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#addFrameworkListener(org.osgi.framework.FrameworkListener)
     */
    @Override
    public void addFrameworkListener( FrameworkListener arg0 )
    {
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener)
     */
    @Override
    public void addServiceListener( ServiceListener listener )
    {
        serviceListeners.add( listener );
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#addServiceListener(org.osgi.framework.ServiceListener, java.lang.String)
     */
    @Override
    public void addServiceListener( ServiceListener listener, String filter )
    {
        serviceListeners.add( listener );
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#createFilter(java.lang.String)
     */
    @Override
    public Filter createFilter( String arg0 )
    {
        return new Filter()
        {

            @Override
            public boolean match( ServiceReference arg0 )
            {
                return true;
            }


            @Override
            public boolean match( Dictionary arg0 )
            {
                return true;
            }


            @Override
            public boolean matchCase( Dictionary arg0 )
            {
                return true;
            }


            @Override
            public boolean matches(Map<String, ?> map)
            {

               return false;
            }

        };
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getAllServiceReferences(java.lang.String, java.lang.String)
     */
    @Override
    public ServiceReference[] getAllServiceReferences( String arg0, String arg1 )
    {
        return null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getBundle()
     */
    @Override
    public Bundle getBundle()
    {
        return theBundle;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getBundle(long)
     */
    @Override
    public Bundle getBundle( long bundleId )
    {
        if ( bundleId == getBundle().getBundleId() )
        {
            return getBundle();
        }

        return null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getBundles()
     */
    @Override
    public Bundle[] getBundles()
    {
        return new Bundle[]
            { getBundle() };
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getDataFile(java.lang.String)
     */
    @Override
    public File getDataFile( String arg0 )
    {
        return null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getProperty(java.lang.String)
     */
    @Override
    public String getProperty( String arg0 )
    {
        return null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getService(org.osgi.framework.ServiceReference)
     */
    @Override
    public Object getService( ServiceReference serviceReference )
    {
        if ( serviceReference instanceof MockServiceReference )
        {
            return ( ( MockServiceReference ) serviceReference ).getServiceRegistration().getService();
        }

        return null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getServiceReference(java.lang.String)
     */
    @Override
    public ServiceReference getServiceReference( String name )
    {
        ServiceRegistration sr = ( ServiceRegistration ) services.get( name );
        return ( sr != null ) ? sr.getReference() : null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#getServiceReferences(java.lang.String, java.lang.String)
     */
    @Override
    public ServiceReference[] getServiceReferences( String arg0, String arg1 )
    {
        return null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String)
     */
    @Override
    public Bundle installBundle( String arg0 )
    {
        return null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#installBundle(java.lang.String, java.io.InputStream)
     */
    @Override
    public Bundle installBundle( String arg0, InputStream arg1 )
    {
        return null;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#registerService(java.lang.String[], java.lang.Object, java.util.Dictionary)
     */
    @Override
    public ServiceRegistration registerService( String[] names, Object service, Dictionary props )
    {
        props.put( Constants.OBJECTCLASS, names );
        ServiceRegistration sr = new MockServiceRegistration( this, service, names, props );

        for ( int i = 0; i < names.length; i++ )
        {
            services.put( names[i], sr );
        }

        fireServiceEvent( sr.getReference(), ServiceEvent.REGISTERED );

        return sr;
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#registerService(java.lang.String, java.lang.Object, java.util.Dictionary)
     */
    @Override
    public ServiceRegistration registerService( String name, Object service, Dictionary props )
    {
        return registerService( new String[]
            { name }, service, props );
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#removeBundleListener(org.osgi.framework.BundleListener)
     */
    @Override
    public void removeBundleListener( BundleListener arg0 )
    {
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#removeFrameworkListener(org.osgi.framework.FrameworkListener)
     */
    @Override
    public void removeFrameworkListener( FrameworkListener arg0 )
    {
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#removeServiceListener(org.osgi.framework.ServiceListener)
     */
    @Override
    public void removeServiceListener( ServiceListener listener )
    {
        serviceListeners.remove( listener );
    }


    /* (non-Javadoc)
     * @see org.osgi.framework.BundleContext#ungetService(org.osgi.framework.ServiceReference)
     */
    @Override
    public boolean ungetService( ServiceReference serviceReference )
    {
        if ( serviceReference instanceof MockServiceReference )
        {
            return ( ( MockServiceReference ) serviceReference ).getServiceRegistration().ungetService();

        }

        return false;
    }


    @Override
    public <S> ServiceRegistration<S> registerService(Class<S> clazz, S service, Dictionary<String, ?> properties)
    {
        return null;
    }


    @Override
    public <S> ServiceReference<S> getServiceReference(Class<S> clazz)
    {
        return null;
    }


    @Override
    public <S> Collection<ServiceReference<S>> getServiceReferences(Class<S> clazz, String filter)
            throws InvalidSyntaxException
    {
        return null;
    }


    @Override
    public Bundle getBundle(String location)
    {
        return null;
    }


    @Override
    public <S> ServiceRegistration<S> registerService(Class<S> clazz, ServiceFactory<S> factory,
            Dictionary<String, ?> properties) {
        // TODO Auto-generated method stub
        return null;
    }


    @Override
    public <S> ServiceObjects<S> getServiceObjects(ServiceReference<S> reference) {
        // TODO Auto-generated method stub
        return null;
    }


    private void fireServiceEvent( ServiceReference ref, int type )
    {
        ServiceEvent se = new ServiceEvent( type, ref );
        for ( Iterator li = serviceListeners.iterator(); li.hasNext(); )
        {
            ( ( ServiceListener ) li.next() ).serviceChanged( se );
        }
    }

    private static class MockServiceRegistration implements ServiceRegistration
    {

        private MockBundleContext bundleContext;
        private Dictionary serviceProps;
        private String[] serviceNames;
        private Object service;
        private ServiceReference serviceRef;
        int refs;


        MockServiceRegistration( MockBundleContext bundleContext, Object service, String[] names, Dictionary props )
        {
            this.bundleContext = bundleContext;
            this.serviceNames = names;
            this.serviceProps = props;
            this.service = service;
            this.serviceRef = new MockServiceReference( this );
        }


        Object getService()
        {
            refs++;
            return service;
        }


        boolean ungetService()
        {
            refs--;
            return refs <= 0;
        }


        @Override
        public ServiceReference getReference()
        {
            return serviceRef;
        }


        @Override
        public void setProperties( Dictionary props )
        {
            serviceProps = props;

            bundleContext.fireServiceEvent( serviceRef, ServiceEvent.MODIFIED );
        }


        @Override
        public void unregister()
        {
            bundleContext.fireServiceEvent( getReference(), ServiceEvent.UNREGISTERING );

            for ( int i = 0; i < serviceNames.length; i++ )
            {
                bundleContext.services.remove( serviceNames[i] );
            }
        }

    };

    private static class MockServiceReference implements ServiceReference
    {
        private MockServiceRegistration msr;


        MockServiceReference( MockServiceRegistration msr )
        {
            this.msr = msr;
        }


        MockServiceRegistration getServiceRegistration()
        {
            return msr;
        }


        @Override
        public Bundle getBundle()
        {
            return msr.bundleContext.getBundle();
        }


        @Override
        public Object getProperty( String prop )
        {
            return msr.serviceProps.get( prop );
        }


        @Override
        public String[] getPropertyKeys()
        {
            List keys = new ArrayList();
            for ( Enumeration ke = msr.serviceProps.keys(); ke.hasMoreElements(); )
            {
                keys.add( ke.nextElement() );
            }
            return ( String[] ) keys.toArray( new String[keys.size()] );
        }


        @Override
        public Bundle[] getUsingBundles()
        {
            return null;
        }


        @Override
        public boolean isAssignableTo( Bundle arg0, String arg1 )
        {
            return false;
        }


        @Override
        public int compareTo( Object reference )
        {
            return -1;
        }

    }
}
