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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;

import com.google.common.collect.ImmutableMap;

public class OsgiServiceUtilTest {

    private BundleContext bundleContext = MockOsgi.newBundleContext();
    private Service1 service1;
    private Service2 service2;

    @Before
    public void setUp() {
        service1 = new Service1();
        service2 = new Service2();
        bundleContext.registerService(ServiceInterface1.class.getName(), service1, null);
        bundleContext.registerService(ServiceInterface2.class.getName(), service2, null);
    }
    
    @After
    public void tearDown() {
        MockOsgi.shutdown(bundleContext);
    }

    @Test
    public void testService3() {
        Service3 service3 = new Service3();
        assertTrue(MockOsgi.injectServices(service3, bundleContext));

        Dictionary<String, Object> service3Config = new Hashtable<String, Object>();
        service3Config.put("prop1", "value1");
        assertTrue(MockOsgi.activate(service3, bundleContext, service3Config));

        assertNotNull(service3.getComponentContext());
        assertEquals(service3Config.get("prop1"), service3.getComponentContext().getProperties().get("prop1"));

        assertSame(service1, service3.getReference1());

        List<ServiceInterface2> references2 = service3.getReferences2();
        assertEquals(1, references2.size());
        assertSame(service2, references2.get(0));

        List<ServiceSuperInterface3> references3 = service3.getReferences3();
        assertEquals(1, references3.size());
        assertSame(service2, references3.get(0));

        List<Map<String, Object>> reference3Configs = service3.getReference3Configs();
        assertEquals(1, reference3Configs.size());
        assertEquals(200, reference3Configs.get(0).get(Constants.SERVICE_RANKING));

        assertTrue(MockOsgi.deactivate(service3, bundleContext));
        assertNull(service3.getComponentContext());
    }

    @Test
    public void testService3_Config() {
        BundleContext bundleContext = MockOsgi.newBundleContext();

        Map<String,Object> initialProperites = ImmutableMap.<String, Object>of("prop1", "value1");

        Service3 service3 = new Service3();
        MockOsgi.activate(service3, bundleContext, initialProperites);
        assertEquals(initialProperites.get("prop1"), service3.getConfig().get("prop1"));

        Map<String,Object> newProperties = ImmutableMap.<String, Object>of("prop2", "value2");
        MockOsgi.modified(service3, bundleContext, newProperties);
        assertEquals(newProperties.get("prop2"), service3.getConfig().get("prop2"));

        newProperties = ImmutableMap.<String, Object>of("prop3", "value3");
        Dictionary<String,Object> newPropertiesDictonary = new Hashtable<String,Object>(newProperties);
        MockOsgi.modified(service3, bundleContext, newPropertiesDictonary);
        assertEquals(newProperties.get("prop3"), service3.getConfig().get("prop3"));

        MockOsgi.modified(service3, bundleContext, "prop3", "value4");
        assertEquals("value4", service3.getConfig().get("prop3"));
    }

    @Test
    public void testService4() {
        Service4 service4 = new Service4();

        assertTrue(MockOsgi.injectServices(service4, bundleContext));
        assertFalse(MockOsgi.activate(service4, bundleContext));

        assertSame(service1, service4.getReference1());
    }

    @Test(expected=NoScrMetadataException.class)
    public void testInjectServicesNoMetadata() {
        MockOsgi.injectServices(new Object(), MockOsgi.newBundleContext());
    }

    @Test(expected=NoScrMetadataException.class)
    public void testActivateNoMetadata() {
        MockOsgi.activate(new Object(), bundleContext);
    }

    @Test(expected=NoScrMetadataException.class)
    public void testDeactivateNoMetadata() {
        MockOsgi.deactivate(new Object(), bundleContext);
    }

    @Test(expected=NoScrMetadataException.class)
    public void testModifiedNoMetadata() {
        MockOsgi.modified(new Object(), MockOsgi.newBundleContext(), ImmutableMap.<String,Object>of());
    }

    @Test
    public void testMockedService() {
        Service5 service5 = Mockito.spy(new Service5());
        Mockito.doReturn(true).when(service5).doRemoteThing();

        MockOsgi.injectServices(service5, bundleContext);
        MockOsgi.activate(service5, bundleContext, (Dictionary<String, Object>) null);
        bundleContext.registerService(ServiceInterface5.class.getName(), service5, null);

        assertSame(service5, bundleContext.getService(
                bundleContext.getServiceReference(ServiceInterface5.class.getName())));
        assertEquals(true, service5.doRemoteThing());
    }

    @Test
    public void testServiceFactoryViaScr() {
        ServiceFactory1 serviceFactory1 = new ServiceFactory1();
        
        MockOsgi.injectServices(serviceFactory1, bundleContext);
        MockOsgi.activate(serviceFactory1, bundleContext, (Dictionary<String, Object>) null);
        bundleContext.registerService(ServiceFactory1.class.getName(), serviceFactory1, null);

        assertSame(serviceFactory1, bundleContext.getService(
                bundleContext.getServiceReference(ServiceFactory1.class.getName())));
    }

    @Test
    public void testServiceFactoryViaManualRegistration() {
        final ServiceFactory1 serviceFactory1 = new ServiceFactory1();
        
        bundleContext.registerService(ServiceFactory1.class.getName(), new ServiceFactory() {
            @Override
            public Object getService(Bundle bundle, ServiceRegistration registration) {
                return serviceFactory1;
            }
            @Override
            public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
                // nothing to do
            }
        }, null);

        assertSame(serviceFactory1, bundleContext.getService(
                bundleContext.getServiceReference(ServiceFactory1.class.getName())));
    }

    
    public interface ServiceInterface1 {
        // no methods
    }

    public interface ServiceInterface1Optional {
        // no methods
    }

    public interface ServiceInterface2 {
        // no methods
    }

    public interface ServiceInterface3 extends ServiceSuperInterface3 {
        // no methods
    }

    public interface ServiceSuperInterface3 {
        // no methods
    }

    @Component(service = ServiceInterface1.class,
            property = Constants.SERVICE_RANKING + ":Integer=100")
    public static class Service1 implements ServiceInterface1 {
        // dummy interface
    }

    @Component(service = { ServiceInterface2.class, ServiceInterface3.class },
            property = Constants.SERVICE_RANKING + ":Integer=200")
    public static class Service2 implements ServiceInterface2, ServiceInterface3 {
        // dummy interface
    }

    @Component(reference = { @Reference(name = "reference2", service = ServiceInterface2.class, cardinality = ReferenceCardinality.AT_LEAST_ONE,
            bind="bindReference2", unbind="unbindReference2") })
    public static class Service3 {

        @Reference(bind="bindReference1", unbind="unbindReference1")
        private ServiceInterface1 reference1;
        @Reference(cardinality = ReferenceCardinality.OPTIONAL, bind="bindReference1Optional", unbind="unbindReference1Optional")
        private ServiceInterface1Optional reference1Optional;

        private List<ServiceReference> references2 = new ArrayList<ServiceReference>();

        @Reference(name = "reference3", service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE,
                bind="bindReference3", unbind="unbindReference3")
        private List<ServiceSuperInterface3> references3 = new ArrayList<ServiceSuperInterface3>();
        private List<Map<String, Object>> reference3Configs = new ArrayList<Map<String, Object>>();

        private ComponentContext componentContext;
        private Map<String, Object> config;

        @Activate
        private void activate(ComponentContext ctx) {
            this.componentContext = ctx;
            this.config = MapUtil.toMap(ctx.getProperties());
        }

        @Deactivate
        private void deactivate(ComponentContext ctx) {
            this.componentContext = null;
        }

        @Modified
        private void modified(Map<String,Object> newConfig) {
            this.config = newConfig;
        }

        public ServiceInterface1 getReference1() {
            return this.reference1;
        }

        public ServiceInterface1Optional getReference1Optional() {
            return this.reference1Optional;
        }

        public List<ServiceInterface2> getReferences2() {
            List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
            for (ServiceReference<?> serviceReference : references2) {
                services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
            }
            return services;
        }

        public List<ServiceSuperInterface3> getReferences3() {
            return this.references3;
        }

        public List<Map<String, Object>> getReference3Configs() {
            return this.reference3Configs;
        }

        public ComponentContext getComponentContext() {
            return this.componentContext;
        }

        public Map<String, Object> getConfig() {
            return config;
        }

        protected void bindReference1Optional(ServiceInterface1Optional service) {
            reference1Optional = service;
        }

        protected void unbindReference1Optional(ServiceInterface1Optional service) {
            reference1Optional = null;
        }

        protected void bindReference1(ServiceInterface1 service) {
            reference1 = service;
        }

        protected void unbindReference1(ServiceInterface1 service) {
            reference1 = null;
        }

        protected void bindReference2(ServiceReference serviceReference) {
            references2.add(serviceReference);
        }

        protected void unbindReference2(ServiceReference serviceReference) {
            references2.remove(serviceReference);
        }

        protected void bindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
            references3.add(service);
            reference3Configs.add(serviceConfig);
        }

        protected void unbindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
            references3.remove(service);
            reference3Configs.remove(serviceConfig);
        }

    }

    public static class Service3OsgiR6 {

        private ServiceInterface1 reference1;
        private ServiceInterface1Optional reference1Optional;
        private List<ServiceReference> references2;
        private List<ServiceSuperInterface3> references3;
        private List<ServiceSuperInterface3> references3Filtered;

        private ComponentContext componentContext;
        private Map<String, Object> config;

        @Activate
        private void activate(ComponentContext ctx) {
            this.componentContext = ctx;
            this.config = MapUtil.toMap(ctx.getProperties());
        }

        @Deactivate
        private void deactivate(ComponentContext ctx) {
            this.componentContext = null;
        }

        @Modified
        private void modified(Map<String,Object> newConfig) {
            this.config = newConfig;
        }

        public ServiceInterface1 getReference1() {
            return this.reference1;
        }

        public ServiceInterface1Optional getReference1Optional() {
            return this.reference1Optional;
        }

        public List<ServiceInterface2> getReferences2() {
            List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
            for (ServiceReference<?> serviceReference : references2) {
                services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
            }
            return services;
        }

        public List<ServiceSuperInterface3> getReferences3() {
            return this.references3;
        }

        public List<ServiceSuperInterface3> getReferences3Filtered() {
            return this.references3Filtered;
        }

        public ComponentContext getComponentContext() {
            return this.componentContext;
        }

        public Map<String, Object> getConfig() {
            return config;
        }

    }

    @Component(reference = { @Reference(name = "reference2", service = ServiceInterface2.class, cardinality = ReferenceCardinality.AT_LEAST_ONE,
            bind="bindReference2", unbind="unbindReference2") })
    public static class Service3StaticGreedy {

        @Reference(bind="bindReference1", unbind="unbindReference1")
        private ServiceInterface1 reference1;
        @Reference(cardinality = ReferenceCardinality.OPTIONAL, bind="bindReference1Optional", unbind="unbindReference1Optional")
        private ServiceInterface1Optional reference1Optional;

        private List<ServiceReference> references2 = new ArrayList<ServiceReference>();

        @Reference(name = "reference3", service = ServiceInterface3.class, cardinality = ReferenceCardinality.MULTIPLE,
                bind="bindReference3", unbind="unbindReference3")
        private List<ServiceSuperInterface3> references3 = new ArrayList<ServiceSuperInterface3>();
        private List<Map<String, Object>> reference3Configs = new ArrayList<Map<String, Object>>();

        private ComponentContext componentContext;
        private Map<String, Object> config;

        @Activate
        private void activate(ComponentContext ctx) {
            this.componentContext = ctx;
            this.config = MapUtil.toMap(ctx.getProperties());
        }

        @Deactivate
        private void deactivate(ComponentContext ctx) {
            this.componentContext = null;
        }

        @Modified
        private void modified(Map<String,Object> newConfig) {
            this.config = newConfig;
        }

        public ServiceInterface1 getReference1() {
            return this.reference1;
        }

        public ServiceInterface1Optional getReference1Optional() {
            return this.reference1Optional;
        }

        public List<ServiceInterface2> getReferences2() {
            List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
            for (ServiceReference<?> serviceReference : references2) {
                services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
            }
            return services;
        }

        public List<ServiceSuperInterface3> getReferences3() {
            return this.references3;
        }

        public List<Map<String, Object>> getReference3Configs() {
            return this.reference3Configs;
        }

        public ComponentContext getComponentContext() {
            return this.componentContext;
        }

        public Map<String, Object> getConfig() {
            return config;
        }

        protected void bindReference1Optional(ServiceInterface1Optional service) {
            reference1Optional = service;
        }

        protected void unbindReference1Optional(ServiceInterface1Optional service) {
            reference1Optional = null;
        }

        protected void bindReference1(ServiceInterface1 service) {
            reference1 = service;
        }

        protected void unbindReference1(ServiceInterface1 service) {
            reference1 = null;
        }

        protected void bindReference2(ServiceReference serviceReference) {
            references2.add(serviceReference);
        }

        protected void unbindReference2(ServiceReference serviceReference) {
            references2.remove(serviceReference);
        }

        protected void bindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
            references3.add(service);
            reference3Configs.add(serviceConfig);
        }

        protected void unbindReference3(ServiceSuperInterface3 service, Map<String, Object> serviceConfig) {
            references3.remove(service);
            reference3Configs.remove(serviceConfig);
        }

    }

    @Component(reference = @Reference(service = ServiceInterface1.class, name = "customName", bind = "customBind", unbind = "customUnbind"))
    public static class Service4 {

        private ServiceInterface1 reference1;

        public ServiceInterface1 getReference1() {
            return this.reference1;
        }

        protected void customBind(ServiceInterface1 service) {
            reference1 = service;
        }

        protected void customUnbind(ServiceInterface1 service) {
            reference1 = null;
        }

    }

    @Component(service = { ServiceInterface5.class })
    public static class Service5 implements ServiceInterface5 {

        @Override
        public boolean doRemoteThing() {
            return false;
        }
    }

    public interface ServiceInterface5 {

        boolean doRemoteThing();

    }

    @Component(service = ServiceFactory1.class, servicefactory = true)
    public static class ServiceFactory1 {
        
    }
        
}
