/*******************************************************************************
 * Copyright (c) 2003, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.internal.serviceregistry;

import java.util.Dictionary;
import org.osgi.framework.*;

/**
 * A reference to a service.
 *
 * <p>
 * The Framework returns <code>ServiceReference</code> objects from the
 * <code>BundleContext.getServiceReference</code> and
 * <code>BundleContext.getServiceReferences</code> methods.
 * <p>
 * A <code>ServiceReference</code> object may be shared between bundles and
 * can be used to examine the properties of the service and to get the service
 * object.
 * <p>
 * Every service registered in the Framework has a unique
 * <code>ServiceRegistration</code> object and may have multiple, distinct
 * <code>ServiceReference</code> objects referring to it.
 * <code>ServiceReference</code> objects associated with a
 * <code>ServiceRegistration</code> object have the same <code>hashCode</code>
 * and are considered equal (more specifically, their <code>equals()</code>
 * method will return <code>true</code> when compared).
 * <p>
 * If the same service object is registered multiple times,
 * <code>ServiceReference</code> objects associated with different
 * <code>ServiceRegistration</code> objects are not equal.
 *
 * @see BundleContext#getServiceReference
 * @see BundleContext#getServiceReferences
 * @see BundleContext#getService
 * @ThreadSafe
 */
public class ServiceReferenceImpl<S> implements ServiceReference<S> {
	/** Registered Service object. */
	private final ServiceRegistrationImpl<S> registration;

	/**
	 * Construct a reference.
	 *
	 */
	ServiceReferenceImpl(ServiceRegistrationImpl<S> registration) {
		this.registration = registration;
		/* We must not dereference registration in the constructor
		 * since it is "leaked" to us in the ServiceRegistrationImpl
		 * constructor.
		 */
	}

	/**
	 * Returns the property value to which the specified property key is mapped
	 * in the properties <code>Dictionary</code> object of the service
	 * referenced by this <code>ServiceReference</code> object.
	 *
	 * <p>
	 * Property keys are case-insensitive.
	 *
	 * <p>
	 * This method must continue to return property values after the service has
	 * been unregistered. This is so references to unregistered services (for
	 * example, <code>ServiceReference</code> objects stored in the log) can
	 * still be interrogated.
	 *
	 * @param key The property key.
	 * @return The property value to which the key is mapped; <code>null</code>
	 *         if there is no property named after the key.
	 */
	@Override
	public Object getProperty(String key) {
		return registration.getProperty(key);
	}

	/**
	 * Returns an array of the keys in the properties <code>Dictionary</code>
	 * object of the service referenced by this <code>ServiceReference</code>
	 * object.
	 *
	 * <p>
	 * This method will continue to return the keys after the service has been
	 * unregistered. This is so references to unregistered services (for
	 * example, <code>ServiceReference</code> objects stored in the log) can
	 * still be interrogated.
	 *
	 * <p>
	 * This method is <i>case-preserving </i>; this means that every key in the
	 * returned array must have the same case as the corresponding key in the
	 * properties <code>Dictionary</code> that was passed to the
	 * {@link BundleContext#registerService(String[],Object,java.util.Dictionary)}
	 * or {@link ServiceRegistration#setProperties} methods.
	 *
	 * @return An array of property keys.
	 */
	@Override
	public String[] getPropertyKeys() {
		return registration.getPropertyKeys();
	}

	/**
	 * Returns the bundle that registered the service referenced by this
	 * <code>ServiceReference</code> object.
	 *
	 * <p>
	 * This method must return <code>null</code> when the service has been
	 * unregistered. This can be used to determine if the service has been
	 * unregistered.
	 *
	 * @return The bundle that registered the service referenced by this
	 *         <code>ServiceReference</code> object; <code>null</code> if
	 *         that service has already been unregistered.
	 * @see BundleContext#registerService(String[],Object,java.util.Dictionary)
	 */
	@Override
	public Bundle getBundle() {
		return registration.getBundle();
	}

	/**
	 * Returns the bundles that are using the service referenced by this
	 * <code>ServiceReference</code> object. Specifically, this method returns
	 * the bundles whose usage count for that service is greater than zero.
	 *
	 * @return An array of bundles whose usage count for the service referenced
	 *         by this <code>ServiceReference</code> object is greater than
	 *         zero; <code>null</code> if no bundles are currently using that
	 *         service.
	 *
	 * @since 1.1
	 */
	@Override
	public Bundle[] getUsingBundles() {
		return registration.getUsingBundles();
	}

	/**
	 * Tests if the bundle that registered the service referenced by this
	 * <code>ServiceReference</code> and the specified bundle use the same
	 * source for the package of the specified class name.
	 * <p>
	 * This method performs the following checks:
	 * <ol>
	 * <li>Get the package name from the specified class name.</li>
	 * <li>For the bundle that registered the service referenced by this
	 * <code>ServiceReference</code> (registrant bundle); find the source for
	 * the package. If no source is found then return <code>true</code> if the
	 * registrant bundle is equal to the specified bundle; otherwise return
	 * <code>false</code>.</li>
	 * <li>If the package source of the registrant bundle is equal to the
	 * package source of the specified bundle then return <code>true</code>;
	 * otherwise return <code>false</code>.</li>
	 * </ol>
	 *
	 * @param bundle The <code>Bundle</code> object to check.
	 * @param className The class name to check.
	 * @return <code>true</code> if the bundle which registered the service
	 *         referenced by this <code>ServiceReference</code> and the
	 *         specified bundle use the same source for the package of the
	 *         specified class name. Otherwise <code>false</code> is returned.
	 *
	 * @since 1.3
	 */
	@Override
	public boolean isAssignableTo(Bundle bundle, String className) {
		return registration.isAssignableTo(bundle, className);
	}

	/**
	 * Compares this <code>ServiceReference</code> with the specified
	 * <code>ServiceReference</code> for order.
	 *
	 * <p>
	 * If this <code>ServiceReference</code> and the specified
	 * <code>ServiceReference</code> have the same
	 * {@link Constants#SERVICE_ID service id} they are equal. This
	 * <code>ServiceReference</code> is less than the specified
	 * <code>ServiceReference</code> if it has a lower
	 * {@link Constants#SERVICE_RANKING service ranking} and greater if it has a
	 * higher service ranking. Otherwise, if this <code>ServiceReference</code>
	 * and the specified <code>ServiceReference</code> have the same
	 * {@link Constants#SERVICE_RANKING service ranking}, this
	 * <code>ServiceReference</code> is less than the specified
	 * <code>ServiceReference</code> if it has a higher
	 * {@link Constants#SERVICE_ID service id} and greater if it has a lower
	 * service id.
	 *
	 * @param object The <code>ServiceReference</code> to be compared.
	 * @return Returns a negative integer, zero, or a positive integer if this
	 *         <code>ServiceReference</code> is less than, equal to, or
	 *         greater than the specified <code>ServiceReference</code>.
	 * @since 1.4
	 */
	@Override
	public int compareTo(Object object) {
		ServiceRegistrationImpl<?> other = ((ServiceReferenceImpl<?>) object).registration;

		final int thisRanking = registration.getRanking();
		final int otherRanking = other.getRanking();
		if (thisRanking != otherRanking) {
			if (thisRanking < otherRanking) {
				return -1;
			}
			return 1;
		}
		final long thisId = registration.getId();
		final long otherId = other.getId();
		if (thisId == otherId) {
			return 0;
		}
		if (thisId < otherId) {
			return 1;
		}
		return -1;
	}

	/**
	 * Returns a hash code value for the object.
	 *
	 * @return  a hash code value for this object.
	 */
	@Override
	public int hashCode() {
		return registration.hashCode();
	}

	/**
	 * Indicates whether some other object is "equal to" this one.
	 *
	 * @param   obj   the reference object with which to compare.
	 * @return  <code>true</code> if this object is the same as the obj
	 *          argument; <code>false</code> otherwise.
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}

		if (!(obj instanceof ServiceReferenceImpl<?>)) {
			return false;
		}

		ServiceReferenceImpl<?> other = (ServiceReferenceImpl<?>) obj;

		return registration == other.registration;
	}

	/**
	 * Return a string representation of this reference.
	 *
	 * @return String
	 */
	@Override
	public String toString() {
		return registration.toString();
	}

	/**
	 * Return the ServiceRegistrationImpl for this ServiceReferenceImpl.
	 *
	 * @return The ServiceRegistrationImpl for this ServiceReferenceImpl.
	 */
	public ServiceRegistrationImpl<S> getRegistration() {
		return registration;
	}

	/**
	 * Return the classes under which the referenced service was registered.
	 *
	 * @return array of class names.
	 */
	String[] getClasses() {
		return registration.getClasses();
	}

	/**
	 * Returns a copy of the properties of the service referenced by this
	 * {@code ServiceReference} object.
	 * <p>
	 * This method will continue to return the properties after the service has
	 * been unregistered. This is so references to unregistered services (for
	 * example, {@code ServiceReference} objects stored in the log) can still be
	 * interrogated.
	 * <p>
	 * The returned {@code Dictionary} object:
	 * <ul>
	 * <li>Must map property values by using property keys in a
	 * <i>case-insensitive manner</i>.</li>
	 * <li>Must return property keys is a <i>case-preserving</i> manner. This
	 * means that the keys must have the same case as the corresponding key in
	 * the properties {@code Dictionary} that was passed to the
	 * {@link BundleContext#registerService(String[],Object,Dictionary)} or
	 * {@link ServiceRegistration#setProperties(Dictionary)} methods.</li>
	 * <li>Is the property of the caller and can be modified by the caller but
	 * any changes are not reflected in the properties of the service.
	 * {@link ServiceRegistration#setProperties(Dictionary)} must be called to
	 * modify the properties of the service.</li>
	 * </ul>
	 *
	 * @return A copy of the properties of the service referenced by this
	 *         {@code ServiceReference} object
	 * @since 1.9
	 */
	@Override
	public Dictionary<String, Object> getProperties() {
		return registration.getPropertiesCopy();
	}
}
