/**
 * 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.cxf.dosgi.dsw.decorator;

import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import junit.framework.TestCase;

import org.easymock.EasyMock;
import org.easymock.IAnswer;
import org.junit.Assert;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;

public class ServiceDecoratorImplTest extends TestCase {
    private static final Map<String, Object> EMPTY = new HashMap<String, Object>();
    private static final URL RES_SD = getResource("/test-resources/sd.xml");
    private static final URL RES_SD1 = getResource("/test-resources/sd1.xml");
    private static final URL RES_SD2 = getResource("/test-resources/sd2.xml");
    private static final URL RES_SD0 = getResource("/test-resources/sd0.xml");
    private static final URL RES_SD_1 = getResource("/test-resources/sd-1.xml");

    @SuppressWarnings("rawtypes")
    public void testAddRemoveDecorations() {
        final Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.acme.foo.Bar"});
        serviceProps.put("test.prop", "xyz");

        Bundle b = createBundleContaining(RES_SD);
        ServiceDecoratorImpl sd = new ServiceDecoratorImpl();
        assertEquals("Precondition failed", 0, sd.decorations.size());
        sd.addDecorations(b);
        assertEquals(1, sd.decorations.size());

        Map<String, Object> target = new HashMap<String, Object>();
        ServiceReference sref = EasyMock.createMock(ServiceReference.class);
        EasyMock.expect(sref.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
            public Object answer() {
                return serviceProps.get(EasyMock.getCurrentArguments()[0]);
            }
        }).anyTimes();
        EasyMock.replay(sref);
        sd.decorate(sref, target);

        Map<String, Object> expected = new HashMap<String, Object>();
        expected.put("test.too", "ahaha");
        assertEquals(expected, target);

        // remove it again
        sd.removeDecorations(b);
        assertEquals(0, sd.decorations.size());
        Map<String, Object> target2 = new HashMap<String, Object>();
        sd.decorate(sref, target2);
        assertEquals(EMPTY, target2);
    }

    public void testAddDecorations() {
        final Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.acme.foo.Bar"});
        serviceProps.put("test.prop", "xyz");

        Map<String, Object> expected = new HashMap<String, Object>();
        expected.put("test.too", "ahaha");
        assertDecorate(serviceProps, expected, RES_SD);
    }

    public void testAddDecorations1() {
        Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.test.A"});

        Map<String, Object> expected = new HashMap<String, Object>();
        expected.put("A", "B");
        expected.put("C", 2);
        assertDecorate(serviceProps, expected, RES_SD1, RES_SD2);
    }

    public void testAddDecorations2() {
        Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.test.D"});

        assertDecorate(serviceProps, EMPTY, RES_SD1, RES_SD2);
    }

    public void testAddDecorations3() {
        Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.test.B"});
        serviceProps.put("x", "y");

        Map<String, Object> expected = new HashMap<String, Object>();
        expected.put("bool", Boolean.TRUE);
        assertDecorate(serviceProps, expected, RES_SD1, RES_SD2);
    }

    public void testAddDecorations4() {
        Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.test.C"});
        serviceProps.put("x", "z");

        Map<String, Object> expected = new HashMap<String, Object>();
        expected.put("bool", Boolean.FALSE);
        assertDecorate(serviceProps, expected, RES_SD1, RES_SD2);
    }

    public void testAddDecorations5() {
        Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.test.C"});
        serviceProps.put("x", "x");

        assertDecorate(serviceProps, EMPTY, RES_SD1, RES_SD2);
    }

    public void testAddDecorations6() {
        Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.test.D"});

        assertDecorate(serviceProps, EMPTY, RES_SD0);
    }

    public void testAddDecorations7() {
        Map<String, Object> serviceProps = new HashMap<String, Object>();
        serviceProps.put(Constants.OBJECTCLASS, new String[] {"org.test.D"});

        assertDecorate(serviceProps, EMPTY, RES_SD_1);
    }

    private void assertDecorate(final Map<String, Object> serviceProps, 
                                Map<String, Object> expected, URL... resources) {
        Map<String, Object> actual = testDecorate(serviceProps, resources);
        assertEquals(expected, actual);
    }

    @SuppressWarnings("rawtypes")
    private Map<String, Object> testDecorate(final Map<String, Object> serviceProps, URL... resources) {
        Bundle b = createBundleContaining(resources);

        ServiceDecoratorImpl sd = new ServiceDecoratorImpl();
        sd.addDecorations(b);

        Map<String, Object> target = new HashMap<String, Object>();
        ServiceReference sref = EasyMock.createMock(ServiceReference.class);
        EasyMock.expect(sref.getProperty((String) EasyMock.anyObject())).andAnswer(new IAnswer<Object>() {
            public Object answer() {
                return serviceProps.get(EasyMock.getCurrentArguments()[0]);
            }
        }).anyTimes();
        EasyMock.replay(sref);
        sd.decorate(sref, target);
        return target;
    }

    private Bundle createBundleContaining(URL... resources) {
        Bundle b = EasyMock.createMock(Bundle.class);
        EasyMock.expect(b.findEntries("OSGI-INF/remote-service", "*.xml", false)).andReturn(
            Collections.enumeration(Arrays.asList(resources))).anyTimes();
        EasyMock.expect(b.getSymbolicName()).andReturn("bundlename");
        EasyMock.replay(b);
        return b;
    }

    private static URL getResource(String path) {
        URL resource = ServiceDecoratorImplTest.class.getResource(path);
        Assert.assertNotNull("Resource " + path + " not found!", resource);
        return resource;
    }

}
