/*
 * 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.commons.osgi;

import java.util.Map;

import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;

/**
 * The <code>ServiceUtil</code> is a utility class providing some
 * useful utility methods for service handling.
 * @since 2.1
 */
public class ServiceUtil {

    /**
     * @deprecated Use {@link #getComparableForServiceRanking(Map, Order)} instead.
     * @param props The service properties.
     * @return the same comparable as returned by {@code getComparableForServiceRanking(Map, Order.ASCENDING)}
     * @see #getComparableForServiceRanking(Map, Order)
     */
    @Deprecated
    public static Comparable<Object> getComparableForServiceRanking(final Map<String, Object> props) {
        return getComparableForServiceRanking(props, Order.ASCENDING);
    }

    /**
     * Create a comparable object out of the service properties. With the result
     * it is possible to compare service properties based on the service ranking
     * of a service. This object acts like {@link ServiceReference#compareTo(Object)}.
     * The comparator will return the services in the given order. In ascending order the 
     * service with the lowest ranking comes first, in descending order the service with the 
     * highest ranking comes first. The latter is useful if you want to have the service 
     * returned first which is also chosen by {@link BundleContext#getServiceReference(String)}.
     * @param props The service properties.
     * @param order The order (either ascending or descending).
     * @return A comparable for the ranking of the service
     * @since 2.4
     */
    public static Comparable<Object> getComparableForServiceRanking(final Map<String, Object> props, Order order) {
        return new ComparableImplementation(props, order);
    }

    private static final class ComparableImplementation implements Comparable<Object> {

        private final Map<String, Object> props;
        private final Order order;

        private ComparableImplementation(Map<String, Object> props, Order order) {
            this.props = props;
            this.order = order;
        }

        @SuppressWarnings("unchecked")
        public int compareTo(Object reference) {
            final Long otherId;
            Object otherRankObj;
            if ( reference instanceof ServiceReference ) {
                final ServiceReference other = (ServiceReference) reference;
                otherId = (Long) other.getProperty(Constants.SERVICE_ID);
                otherRankObj = other.getProperty(Constants.SERVICE_RANKING);
            } else if (reference instanceof Map){
                final Map<String, Object> otherProps = (Map<String, Object>)reference;
                otherId = (Long) otherProps.get(Constants.SERVICE_ID);
                otherRankObj = otherProps.get(Constants.SERVICE_RANKING);
            } else {
                final ComparableImplementation other = (ComparableImplementation)reference;
                otherId = (Long) other.props.get(Constants.SERVICE_ID);
                otherRankObj = other.props.get(Constants.SERVICE_RANKING);
            }
            final Long id = (Long) props.get(Constants.SERVICE_ID);
            if (id.equals(otherId)) {
                return 0; // same service
            }

            Object rankObj = props.get(Constants.SERVICE_RANKING);

            // If no rank, then spec says it defaults to zero.
            rankObj = (rankObj == null) ? new Integer(0) : rankObj;
            otherRankObj = (otherRankObj == null) ? new Integer(0) : otherRankObj;

            // If rank is not Integer, then spec says it defaults to zero.
            Integer rank = (rankObj instanceof Integer)
                ? (Integer) rankObj : new Integer(0);
            Integer otherRank = (otherRankObj instanceof Integer)
                ? (Integer) otherRankObj : new Integer(0);

            // Sort by rank.
            if (rank.compareTo(otherRank) < 0) {
                return order.lessThan; // lower rank
            } else if (rank.compareTo(otherRank) > 0) {
                return order.greaterThan; // higher rank
            }

            // If ranks are equal, then sort by service id.
            return (id.compareTo(otherId) < 0) ? order.greaterThan : order.lessThan;
        }

        @Override
        public boolean equals(Object obj) {
            if ( obj instanceof ComparableImplementation ) {
                return this.props.equals(((ComparableImplementation)obj).props);
            }
            return false;
        }

        @Override
        public int hashCode() {
            return this.props.hashCode();
        }
    }
}
