/*
 * 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.assertNull;
import static org.junit.Assert.assertSame;

import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3StaticGreedy;
import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3StaticGreedyImpl;
import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1;
import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1Optional;
import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface2;
import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface3;
import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceSuperInterface3;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;

@RunWith(MockitoJUnitRunner.class)
public class MockBundleContextStaticGreedyReferencesTest {

    private BundleContext bundleContext;
    private ServiceRegistration reg1a;
    private ServiceRegistration reg2a;

    @Mock
    private ServiceInterface1 dependency1a;
    @Mock
    private ServiceInterface1 dependency1b;
    @Mock
    private ServiceInterface1Optional dependency1aOptional;
    @Mock
    private ServiceInterface1Optional dependency1bOptional;
    @Mock
    private ServiceInterface2 dependency2a;
    @Mock
    private ServiceInterface2 dependency2b;
    @Mock
    private ServiceSuperInterface3 dependency3a;
    @Mock
    private ServiceSuperInterface3 dependency3b;

    @Before
    public void setUp() {
        bundleContext = MockOsgi.newBundleContext();

        // setup service instance with only minimum mandatory references
        reg1a = bundleContext.registerService(ServiceInterface1.class.getName(), dependency1a, null);
        reg2a = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2a, null);

        Service3StaticGreedy service = new Service3StaticGreedyImpl();
        MockOsgi.injectServices(service, bundleContext);
        MockOsgi.activate(service, bundleContext);
        bundleContext.registerService(Service3StaticGreedy.class.getName(), service, null);

        assertDependency1(dependency1a);
        assertDependency1Optional(null);
        assertDependencies2(dependency2a);
        assertDependencies3();
    }

    @Test
    public void testAddRemoveOptionalUnaryService() {
        ServiceRegistration reg1aOptional = bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1aOptional, null);
        assertDependency1Optional(dependency1aOptional);

        reg1aOptional.unregister();
        assertDependency1Optional(null);
    }

    public void testAddOptionalUnaryService_TooMany() {
        bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1aOptional, null);
        assertDependency1Optional(dependency1aOptional);

        // in real OSGi this should fail - but this is not covered by the current implementation. so test the real implementation here.
        bundleContext.registerService(ServiceInterface1Optional.class.getName(), dependency1bOptional, null);
        assertDependency1Optional(dependency1bOptional);
    }

    @Test
    public void testAddMandatoryUnaryService_TooMany() {
        // should not throw an exception although mandatory unary reference is already set
        bundleContext.registerService(ServiceInterface1.class.getName(), dependency1b, null);
    }

    @Test(expected = ReferenceViolationException.class)
    public void testRemoveMandatoryUnaryService_TooMany() {
        reg1a.unregister();
    }

    @Test
    public void testAddRemoveOptionalMultipleService() {
        ServiceRegistration reg3a = bundleContext.registerService(ServiceInterface3.class.getName(), dependency3a, null);
        assertDependencies3(dependency3a);

        ServiceRegistration reg3b = bundleContext.registerService(ServiceInterface3.class.getName(), dependency3b, null);
        assertDependencies3(dependency3a, dependency3b);

        reg3a.unregister();
        assertDependencies3(dependency3b);

        reg3b.unregister();
        assertDependencies3();
    }

    @Test
    public void testAddRemoveMandatoryMultipleService() {
        ServiceRegistration reg2b = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2b, null);
        assertDependencies2(dependency2a, dependency2b);

        reg2b.unregister();
        assertDependencies2(dependency2a);
    }

    @Test(expected = ReferenceViolationException.class)
    public void testAddRemoveMandatoryMultipleService_FailReg2aUnregister() {
        ServiceRegistration reg2b = bundleContext.registerService(ServiceInterface2.class.getName(), dependency2b, null);
        assertDependencies2(dependency2a, dependency2b);

        reg2b.unregister();
        assertDependencies2(dependency2a);

        // this should fail
        reg2a.unregister();
    }

    @Test
    public void testReferenceWithTargetFilter() {
        assertDependencies3Filtered();

        bundleContext.registerService(ServiceInterface3.class.getName(), dependency3a,
                MapUtil.toDictionary(ImmutableMap.<String, Object>of("prop1", "abc")));

        bundleContext.registerService(ServiceInterface3.class.getName(), dependency3b,
                MapUtil.toDictionary(ImmutableMap.<String, Object>of("prop1", "def")));

        assertDependencies3Filtered(dependency3a);
    }

    private void assertDependency1(ServiceInterface1 instance) {
        Service3StaticGreedy service = getService();
        if (instance == null) {
            assertNull(service.getReference1());
        }
        else {
            assertSame(instance, service.getReference1());
        }
    }

    private void assertDependency1Optional(ServiceInterface1Optional instance) {
        Service3StaticGreedy service = getService();
        if (instance == null) {
            assertNull(service.getReference1Optional());
        }
        else {
            assertSame(instance, service.getReference1Optional());
        }
    }

    private void assertDependencies2(ServiceInterface2... instances) {
        Service3StaticGreedy service = getService();
        assertEquals(ImmutableSet.<ServiceInterface2>copyOf(instances),
                ImmutableSet.<ServiceInterface2>copyOf(service.getReferences2()));
    }

    private void assertDependencies3(ServiceSuperInterface3... instances) {
        Service3StaticGreedy service = getService();
        assertEquals(ImmutableSet.<ServiceSuperInterface3>copyOf(instances),
                ImmutableSet.<ServiceSuperInterface3>copyOf(service.getReferences3()));
    }

    private Service3StaticGreedy getService() {
        ServiceReference<?> serviceRef = bundleContext.getServiceReference(Service3StaticGreedy.class.getName());
        return (Service3StaticGreedy)bundleContext.getService(serviceRef);
    }

    private void assertDependencies3Filtered(ServiceSuperInterface3... instances) {
        Service3StaticGreedy service = getService();
        assertEquals(ImmutableSet.<ServiceSuperInterface3>copyOf(instances),
                ImmutableSet.<ServiceSuperInterface3>copyOf(service.getReferences3Filtered()));
    }

}
