/**
 * 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() throws Throwable {
                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() throws Throwable {
                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;
    }

}
