/*
 * Copyright (c) OSGi Alliance (2009, 2015). All Rights Reserved.
 *
 * Licensed 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.osgi.service.remoteserviceadmin;

import java.util.Collection;
import java.util.Map;
import org.osgi.annotation.versioning.ProviderType;
import org.osgi.framework.ServiceReference;

/**
 * A Remote Service Admin manages the import and export of services.
 * 
 * A Distribution Provider can expose a control interface. This interface allows
 * a Topology Manager to control the export and import of services.
 * 
 * The API allows a Topology Manager to export a service, to import a service,
 * and find out about the current imports and exports.
 * 
 * @ThreadSafe
 * @author $Id: 49d931591212a8f81060c6721589fd058374f11e $
 */
@ProviderType
public interface RemoteServiceAdmin {

	/**
	 * Export a service to a given Endpoint. The Remote Service Admin must
	 * create an Endpoint from the given description that can be used by other
	 * Distribution Providers to connect to this Remote Service Admin and use
	 * the exported service.
	 * 
	 * The property keys of a Service Reference are case insensitive while the
	 * property keys of the specified {@code properties} map are case sensitive.
	 * A property key in the specified {@code properties} map must therefore
	 * override any case variant property key in the properties of the specified
	 * Service Reference.
	 * 
	 * <p>
	 * If the caller does not have the appropriate
	 * {@code EndpointPermission[endpoint,EXPORT]} for an Endpoint, and the Java
	 * Runtime Environment supports permissions, then the
	 * {@link ExportRegistration#getException() getException} method on the
	 * corresponding returned {@link ExportRegistration} will return a
	 * {@code SecurityException}.
	 * 
	 * @param reference The Service Reference to export.
	 * @param properties The properties to create a local Endpoint that can be
	 *        implemented by this Remote Service Admin. If this is {@code null},
	 *        the Endpoint will be determined by the properties on the service.
	 *        The properties are the same as given for an exported service. They
	 *        override any properties in the specified Service Reference (case
	 *        insensitive). The properties {@code objectClass} and
	 *        {@code service.id}, in any case variant, are ignored. Those
	 *        properties in the Service Reference cannot be overridden. This
	 *        parameter can be {@code null}, this should be treated as an empty
	 *        map.
	 * @return A {@code Collection} of {@link ExportRegistration}s for the
	 *         specified Service Reference and properties. Multiple Export
	 *         Registrations may be returned because a single service can be
	 *         exported to multiple Endpoints depending on the available
	 *         configuration type properties and the intents that they support.
	 *         The result is never {@code null} but may be empty if this Remove
	 *         Service Admin does not recognize any of the configuration types,
	 *         or if they Remote Service Admin cannot support the relevant
	 *         intents.
	 * @throws IllegalArgumentException If any of the properties for this
	 *         configuration type has a value that is not syntactically correct,
	 *         or if the service properties and the overlaid properties do not
	 *         contain a {@link RemoteConstants#SERVICE_EXPORTED_INTERFACES}
	 *         entry. This means that implementations must not ignore invalid
	 *         values for property names that they recognize.
	 */
	Collection<ExportRegistration> exportService(ServiceReference<?> reference, Map<String, ?> properties);

	/**
	 * Import a service from an Endpoint. The Remote Service Admin must use the
	 * given Endpoint to create a proxy. This method can return {@code null} if
	 * the service could not be imported.
	 * 
	 * @param endpoint The Endpoint Description to be used for import.
	 * @return An Import Registration that combines the Endpoint Description and
	 *         the Service Reference or {@code null} if the Endpoint could not
	 *         be imported.
	 * @throws SecurityException If the caller does not have the appropriate
	 *         {@code EndpointPermission[endpoint,IMPORT]} for the Endpoint, and
	 *         the Java Runtime Environment supports permissions.
	 */
	ImportRegistration importService(EndpointDescription endpoint);

	/**
	 * Return the currently active Export References.
	 * 
	 * <p>
	 * If the caller does not have the appropriate
	 * {@code EndpointPermission[endpoint,READ]} for an Endpoint, and the Java
	 * Runtime Environment supports permissions, then returned collection will
	 * not contain a reference to the exported Endpoint.
	 * 
	 * @return A {@code Collection} of {@link ExportReference}s that are
	 *         currently active.
	 */
	Collection<ExportReference> getExportedServices();

	/**
	 * Return the currently active Import References.
	 * 
	 * <p>
	 * If the caller does not have the appropriate
	 * {@code EndpointPermission[endpoint,READ]} for an Endpoint, and the Java
	 * Runtime Environment supports permissions, then returned collection will
	 * not contain a reference to the imported Endpoint.
	 * 
	 * @return A {@code Collection} of {@link ImportReference}s that are
	 *         currently active.
	 */
	Collection<ImportReference> getImportedEndpoints();

}
