/*
 * 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.testing.mock.osgi.context;

import java.lang.reflect.Array;
import java.util.Dictionary;
import java.util.Map;

import org.apache.sling.testing.mock.osgi.MapUtil;
import org.apache.sling.testing.mock.osgi.MockEventAdmin;
import org.apache.sling.testing.mock.osgi.MockOsgi;
import org.osgi.annotation.versioning.ConsumerType;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.ComponentContext;

/**
 * Defines OSGi context objects and helper methods. Should not be used directly
 * but via the {@link org.apache.sling.testing.mock.osgi.junit.OsgiContext} JUnit rule.
 */
@ConsumerType
public class OsgiContextImpl {

    protected ComponentContext componentContext;

    /**
     * Setup actions before test method execution
     */
    protected void setUp() {
        registerDefaultServices();
    }
    
    /**
     * Teardown actions after test method execution
     */
    protected void tearDown() {
        if (componentContext != null) {
            // deactivate all services
            MockOsgi.shutdown(componentContext.getBundleContext());
        }

        this.componentContext = null;
    }

    /**
     * Default services that should be available for every unit test
     */
    private void registerDefaultServices() {
        registerInjectActivateService(new MockEventAdmin());
    }
    
    /**
     * @return OSGi component context
     */
    public final ComponentContext componentContext() {
        if (this.componentContext == null) {
            this.componentContext = MockOsgi.newComponentContext();
        }
        return this.componentContext;
    }

    /**
     * @return OSGi Bundle context
     */
    public final BundleContext bundleContext() {
        return componentContext().getBundleContext();
    }

    /**
     * Registers a service in the mocked OSGi environment.
     * @param <T> Service type
     * @param service Service instance
     * @return Registered service instance
     */
    public final <T> T registerService(final T service) {
        return registerService(null, service, (Map<String,Object>)null);
    }

    /**
     * Registers a service in the mocked OSGi environment.
     * @param <T> Service type
     * @param serviceClass Service class
     * @param service Service instance
     * @return Registered service instance
     */
    public final <T> T registerService(final Class<T> serviceClass, final T service) {
        return registerService(serviceClass, service, (Map<String,Object>)null);
    }

    /**
     * Registers a service in the mocked OSGi environment.
     * @param <T> Service type
     * @param serviceClass Service class
     * @param service Service instance
     * @param properties Service properties (optional)
     * @return Registered service instance
     */
    public final <T> T registerService(final Class<T> serviceClass, final T service, final Map<String, Object> properties) {
        Dictionary<String, Object> serviceProperties = MapUtil.toDictionary(properties);
        bundleContext().registerService(serviceClass != null ? serviceClass.getName() : null, service, serviceProperties);
        return service;
    }

    /**
     * Registers a service in the mocked OSGi environment.
     * @param <T> Service type
     * @param serviceClass Service class
     * @param service Service instance
     * @param properties Service properties (optional)
     * @return Registered service instance
     */
    public final <T> T registerService(final Class<T> serviceClass, final T service, final Object... properties) {
        return registerService(serviceClass, service, MapUtil.toMap(properties));
    }
    
    /**
     * Injects dependencies, activates and registers a service in the mocked
     * OSGi environment.
     * @param <T> Service type
     * @param service Service instance
     * @return Registered service instance
     */
    public final <T> T registerInjectActivateService(final T service) {
        return registerInjectActivateService(service, (Map<String,Object>)null);
    }

    /**
     * Injects dependencies, activates and registers a service in the mocked
     * OSGi environment.
     * @param <T> Service type
     * @param service Service instance
     * @param properties Service properties (optional)
     * @return Registered service instance
     */
    public final <T> T registerInjectActivateService(final T service, final Map<String, Object> properties) {
        MockOsgi.injectServices(service, bundleContext(), properties);
        MockOsgi.activate(service, bundleContext(), properties);
        registerService(null, service, properties);
        return service;
    }

    /**
     * Injects dependencies, activates and registers a service in the mocked
     * OSGi environment.
     * @param <T> Service type
     * @param service Service instance
     * @param properties Service properties (optional)
     * @return Registered service instance
     */
    public final <T> T registerInjectActivateService(final T service, final Object... properties) {
        return registerInjectActivateService(service, MapUtil.toMap(properties));
    }

    /**
     * Lookup a single service
     * @param <ServiceType> Service type
     * @param serviceType The type (interface) of the service.
     * @return The service instance, or null if the service is not available.
     */
    @SuppressWarnings("unchecked")
    public final <ServiceType> ServiceType getService(final Class<ServiceType> serviceType) {
        ServiceReference serviceReference = bundleContext().getServiceReference(serviceType.getName());
        if (serviceReference != null) {
            return (ServiceType)bundleContext().getService(serviceReference);
        } else {
            return null;
        }
    }

    /**
     * Lookup one or several services
     * @param <ServiceType> Service type
     * @param serviceType The type (interface) of the service.
     * @param filter An optional filter (LDAP-like, see OSGi spec)
     * @return The services instances or an empty array.
     * @throws RuntimeException If the <code>filter</code> string is not a valid OSGi service filter string.
     */
    @SuppressWarnings("unchecked")
    public final <ServiceType> ServiceType[] getServices(final Class<ServiceType> serviceType, final String filter) {
        try {
            ServiceReference[] serviceReferences = bundleContext().getServiceReferences(serviceType.getName(), filter);
            if (serviceReferences != null) {
                ServiceType[] services = (ServiceType[])Array.newInstance(serviceType, serviceReferences.length);
                for (int i = 0; i < serviceReferences.length; i++) {
                    services[i] = (ServiceType)bundleContext().getService(serviceReferences[i]);
                }
                return services;
            } else {
                return (ServiceType[])Array.newInstance(serviceType, 0);
            }
        } catch (InvalidSyntaxException ex) {
            throw new RuntimeException("Invalid filter syntax: " + filter, ex);
        }
    }

}
