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

import java.util.Arrays;
import java.util.Hashtable;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;

/** 
 * Test the service-ranking based sorting of mock service references
 */
@SuppressWarnings("null")
public class MockServiceReferencesSortTest {
    
    private BundleContext bundleContext;

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

    @After
    public void tearDown() {
        MockOsgi.shutdown(bundleContext);
    }

    @Test
    public void testAllWithRanking() {
        registerStringServiceWithRanking("A", 3);
        registerStringServiceWithRanking("B", 5);
        registerStringServiceWithRanking("C", 4);
        registerStringServiceWithRanking("D", 1);
        registerStringServiceWithRanking("E", 2);
        
        assertEquals("DEACB", getSortedServicesString());
        assertEquals("B", bundleContext.getService(bundleContext.getServiceReference(String.class)));
    }

    @Test
    public void testAllWithoutRanking() {
        registerStringServiceWithoutRanking("A");
        registerStringServiceWithoutRanking("B");
        registerStringServiceWithoutRanking("C");
        registerStringServiceWithoutRanking("D");
        registerStringServiceWithoutRanking("E");
        
        assertEquals("EDCBA", getSortedServicesString());
        assertEquals("A", bundleContext.getService(bundleContext.getServiceReference(String.class)));
    }

    @Test
    public void testMixed() {
        registerStringServiceWithoutRanking("A");
        registerStringServiceWithRanking("B", 5);
        registerStringServiceWithoutRanking("C");
        registerStringServiceWithRanking("D", 10);
        registerStringServiceWithoutRanking("E");
        
        assertEquals("ECABD", getSortedServicesString());
        assertEquals("D", bundleContext.getService(bundleContext.getServiceReference(String.class)));
    }

    private ServiceRegistration<?> registerStringServiceWithoutRanking(String serviceValue) {
        return bundleContext.registerService(String.class, serviceValue, new Hashtable<String, Object>());
    }

    private ServiceRegistration<?> registerStringServiceWithRanking(String serviceValue, int index) {
        final Hashtable<String, Object> props = new Hashtable<String, Object>();
        props.put(Constants.SERVICE_RANKING, new Integer(index));
        return bundleContext.registerService(String.class, serviceValue, props);
    }
    
    /** Register services with a specific ranking, sort their references and 
     *  return their concatenated toString() values.
     *  Use to test service references sorting.
     */
    private String getSortedServicesString() {
        ServiceReference<?>[] refs = null;
        try {
            refs = bundleContext.getServiceReferences(String.class.getName(), null);
        }
        catch (InvalidSyntaxException ise) {
            fail("Unexpected InvalidSyntaxException");
        }
        assertNotNull("Expecting our service references", refs);
        Arrays.sort(refs);
        
        final StringBuilder sb = new StringBuilder();
        for(ServiceReference<?> ref : refs) {
            sb.append(bundleContext.getService(ref).toString());
            bundleContext.ungetService(ref);
        }
        
        return sb.toString();
    }

}
