/*
 * Copyright (c) OSGi Alliance (2010, 2013). 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.coordinator;

import java.util.List;
import java.util.Map;
import org.osgi.annotation.versioning.ProviderType;
import org.osgi.framework.Bundle;

/**
 * A Coordination object is used to coordinate a number of independent
 * Participants.
 * 
 * <p>
 * Once a Coordination is {@link Coordinator#create(String, long) created}, it
 * can be used to add {@link Participant} objects. When the Coordination is
 * ended, the participants are {@link Participant#ended(Coordination) notified}.
 * A Coordination can also fail for various reasons. When this occurs, the
 * participants are {@link Participant#failed(Coordination) notified} of the
 * failure.
 * 
 * <p>
 * A Coordination must be in one of two states, either ACTIVE or TERMINATED. The
 * transition between ACTIVE and TERMINATED must be atomic, ensuring that a
 * Participant can be guaranteed of either receiving an exception when adding
 * itself to a Coordination or of receiving notification the Coordination has
 * terminated.
 * 
 * <p>
 * A Coordination object is thread safe and can be passed as a parameter to
 * other parties regardless of the threads these parties use.
 * 
 * <p>
 * The following example code shows how a Coordination should be used.
 * 
 * <pre>
 * void foo() {
 *   Coordination c = coordinator.create(&quot;work&quot;, 0);
 *   try {
 *     doWork(c);
 *   }
 *   catch (Exception e) {
 *     c.fail(e);
 *   }
 *   finally {
 *     c.end();
 *   }
 * }
 * </pre>
 * 
 * @ThreadSafe
 * @author $Id$
 */
@ProviderType
public interface Coordination {

	/**
	 * A singleton exception that will be the failure cause when a Coordination
	 * times out.
	 */
	Exception	TIMEOUT		= new SingletonException("TIMEOUT");

	/**
	 * A singleton exception that will be the failure cause when the
	 * Coordinations created by a bundle are terminated because the bundle
	 * released the Coordinator service.
	 */
	Exception	RELEASED	= new SingletonException("RELEASED");

	/**
	 * A singleton exception that will be the failure cause when a Coordination
	 * has been orphaned.
	 */
	Exception	ORPHANED	= new SingletonException("ORPHANED");

	/**
	 * Returns the id assigned to this Coordination.
	 * 
	 * The id is assigned by the {@link Coordinator} service which created this
	 * Coordination and is unique among all the Coordinations created by the
	 * Coordinator service and must not be reused as long as the Coordinator
	 * service remains registered. The id must be positive and monotonically
	 * increases for each Coordination created by the Coordinator service.
	 * 
	 * @return The id assigned to this Coordination.
	 */
	long getId();

	/**
	 * Returns the name of this Coordination.
	 * 
	 * The name is specified when this Coordination was created.
	 * 
	 * @return The name of this Coordination.
	 * 
	 */
	String getName();

	/**
	 * Terminate this Coordination normally.
	 * 
	 * <p>
	 * If this Coordination has been {@link #push() pushed} on the thread local
	 * Coordination stack of another thread, this method does nothing except
	 * throw a CoordinationException of type
	 * {@link CoordinationException#WRONG_THREAD}.
	 * 
	 * <p>
	 * If this Coordination has been {@link #push() pushed} on the thread local
	 * Coordination stack of this thread but is not the
	 * {@link Coordinator#peek() current Coordination}, then the Coordinations
	 * on the thread local Coordination stack above this Coordination must be
	 * terminated and removed from the thread local Coordination stack before
	 * this Coordination is terminated. Each of these Coordinations, starting
	 * with the current Coordination, will be {@link #end() terminated normally}
	 * . If the termination throws a {@link CoordinationException}, then the
	 * next Coordination on the thread local Coordination stack will be
	 * {@link #fail(Throwable) terminated as a failure} with a failure cause of
	 * the thrown CoordinationException. At the end of this process, this
	 * Coordination will be the current Coordination and will have been
	 * terminated as a failure if any of the terminated Coordinations threw a
	 * CoordinationException
	 * 
	 * <p>
	 * If this Coordination is the {@link Coordinator#peek() current
	 * Coordination}, then it will be {@link Coordinator#pop() removed} from the
	 * thread local Coordination stack.
	 * 
	 * <p>
	 * If this Coordination is already terminated, a CoordinationException is
	 * thrown. If this Coordination was terminated as a failure, the
	 * {@link #getFailure() failure cause} will be the cause of the thrown
	 * CoordinationException.
	 * 
	 * <p>
	 * Otherwise, this Coordination is terminated normally and then all
	 * registered {@link #getParticipants() Participants} are
	 * {@link Participant#ended(Coordination) notified}. Participants should
	 * finalize any work associated with this Coordination. The successful
	 * return of this method indicates that the Coordination has terminated
	 * normally and all registered Participants have been notified of the normal
	 * termination.
	 * 
	 * <p>
	 * It is possible that one of the Participants throws an exception during
	 * notification. If this happens, this Coordination is considered to have
	 * partially failed and this method must throw a CoordinationException of
	 * type {@link CoordinationException#PARTIALLY_ENDED} after all the
	 * registered Participants have been notified.
	 * 
	 * @throws CoordinationException If this Coordination has failed, including
	 *         timed out, or partially failed or this Coordination is on the
	 *         thread local Coordination stack of another thread.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[INITIATE]} for this Coordination.
	 */
	void end();

	/**
	 * Terminate this Coordination as a failure with the specified failure
	 * cause.
	 * 
	 * <p>
	 * If this Coordination is already {@link #isTerminated() terminated}, this
	 * method does nothing and returns {@code false}.
	 * 
	 * <p>
	 * Otherwise, this Coordination is terminated as a failure with the
	 * specified failure cause and then all registered
	 * {@link #getParticipants() Participants} are
	 * {@link Participant#failed(Coordination) notified}. Participants should
	 * discard any work associated with this Coordination. This method will
	 * return {@code true}.
	 * 
	 * <p>
	 * If this Coordination has been {@link #push() pushed} onto a thread local
	 * Coordination stack, this Coordination is not removed from the stack. The
	 * creator of this Coordination must still call {@link #end()} on this
	 * Coordination to cause it to be removed from the thread local Coordination
	 * stack.
	 * 
	 * @param cause The failure cause. The failure cause must not be
	 *        {@code null}.
	 * @return {@code true} if this Coordination was active and was terminated
	 *         by this method, otherwise {@code false}.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[PARTICIPATE]} for this
	 *         Coordination.
	 */
	boolean fail(Throwable cause);

	/**
	 * Returns the failure cause of this Coordination.
	 * 
	 * <p>
	 * If this Coordination has {@link #fail(Throwable) failed}, then this
	 * method will return the failure cause.
	 * 
	 * <p>
	 * If this Coordination timed out, this method will return {@link #TIMEOUT}
	 * as the failure cause. If this Coordination was active when the bundle
	 * that created it released the {@link Coordinator} service, this method
	 * will return {@link #RELEASED} as the failure cause. If the Coordination
	 * was orphaned, this method will return {@link #ORPHANED} as the failure
	 * cause.
	 * 
	 * @return The failure cause of this Coordination or {@code null} if this
	 *         Coordination has not terminated as a failure.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[INITIATE]} for this Coordination.
	 */
	Throwable getFailure();

	/**
	 * Returns whether this Coordination is terminated.
	 * 
	 * @return {@code true} if this Coordination is terminated, otherwise
	 *         {@code false} if this Coordination is active.
	 */
	boolean isTerminated();

	/**
	 * Register a Participant with this Coordination.
	 * 
	 * <p>
	 * Once a Participant is registered with this Coordination, it is guaranteed
	 * to receive a notification for either
	 * {@link Participant#ended(Coordination) normal} or
	 * {@link Participant#failed(Coordination) failure} termination when this
	 * Coordination is terminated.
	 * 
	 * <p>
	 * Participants are registered using their object identity. Once a
	 * Participant is registered with this Coordination, subsequent attempts to
	 * register the Participant again with this Coordination are ignored and the
	 * Participant is only notified once when this Coordination is terminated.
	 * 
	 * <p>
	 * A Participant can only be registered with a single active Coordination at
	 * a time. If a Participant is already registered with an active
	 * Coordination, attempts to register the Participation with another active
	 * Coordination will block until the Coordination the Participant is
	 * registered with terminates. Notice that in edge cases the notification to
	 * the Participant that this Coordination has terminated can happen before
	 * this method returns.
	 * 
	 * <p>
	 * Attempting to register a Participant with a {@link #isTerminated()
	 * terminated} Coordination will result in a CoordinationException being
	 * thrown.
	 * 
	 * <p>
	 * The ordering of notifying Participants must follow the reverse order in
	 * which the Participants were registered.
	 * 
	 * @param participant The Participant to register with this Coordination.
	 *        The participant must not be {@code null}.
	 * @throws CoordinationException If the Participant could not be registered
	 *         with this Coordination. This exception should normally not be
	 *         caught by the caller but allowed to be caught by the initiator of
	 *         this Coordination.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[PARTICIPATE]} for this
	 *         Coordination.
	 */
	void addParticipant(Participant participant);

	/**
	 * Returns a snapshot of the Participants registered with this Coordination.
	 * 
	 * @return A snapshot of the Participants registered with this Coordination.
	 *         If no Participants are registered with this Coordination, the
	 *         returned list will be empty. The list is ordered in the order the
	 *         Participants were registered. The returned list is the property
	 *         of the caller and can be modified by the caller.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[INITIATE]} for this Coordination.
	 */
	List<Participant> getParticipants();

	/**
	 * Returns the variable map associated with this Coordination.
	 * 
	 * Each Coordination has a map that can be used for communicating between
	 * different Participants. The key of the map is a class, allowing for
	 * private data to be stored in the map by using implementation classes or
	 * shared data by using shared interfaces.
	 * 
	 * The returned map is not synchronized. Users of the map must synchronize
	 * on the Map object while making changes.
	 * 
	 * @return The variable map associated with this Coordination.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[PARTICIPANT]} for this
	 *         Coordination.
	 */
	Map<Class<?>, Object> getVariables();

	/**
	 * Extend the time out of this Coordination.
	 * 
	 * <p>
	 * Participants can call this method to extend the timeout of this
	 * Coordination with at least the specified time. This can be done by
	 * Participants when they know a task will take more than normal time.
	 * 
	 * <p>
	 * This method will return the new deadline if an extension took place or
	 * the current deadline if, for whatever reason, no extension takes place.
	 * Note that if a maximum timeout is in effect, the deadline may not be
	 * extended by as much as was requested, if at all. If there is no deadline,
	 * zero is returned. Specifying a timeout extension of 0 will return the
	 * existing deadline.
	 * 
	 * @param timeMillis The time in milliseconds to extend the current timeout.
	 *        If the initial timeout was specified as 0, no extension must take
	 *        place. A zero must have no effect.
	 * @return The new deadline in milliseconds. If the specified time is 0, the
	 *         existing deadline is returned. If this Coordination was created
	 *         with an initial timeout of 0, no timeout is set and 0 is
	 *         returned.
	 * @throws CoordinationException If this Coordination
	 *         {@link #isTerminated() is terminated}.
	 * @throws IllegalArgumentException If the specified time is negative.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[PARTICIPATE]} for this
	 *         Coordination.
	 */
	long extendTimeout(long timeMillis);

	/**
	 * Wait until this Coordination is terminated and all registered
	 * Participants have been notified.
	 * 
	 * @param timeMillis Maximum time in milliseconds to wait. Specifying a time
	 *        of 0 will wait until this Coordination is terminated.
	 * @throws InterruptedException If the wait is interrupted.
	 * @throws IllegalArgumentException If the specified time is negative.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[PARTICIPATE]} for this
	 *         Coordination.
	 */

	void join(long timeMillis) throws InterruptedException;

	/**
	 * Push this Coordination object onto the thread local Coordination stack to
	 * make it the {@link Coordinator#peek() current Coordination}.
	 * 
	 * @return This Coordination.
	 * @throws CoordinationException If this Coordination is already on the any
	 *         thread's thread local Coordination stack or this Coordination
	 *         {@link #isTerminated() is terminated}.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[INITIATE]} for this Coordination.
	 */
	Coordination push();

	/**
	 * Returns the thread in whose thread local Coordination stack this
	 * Coordination has been {@link #push() pushed}.
	 * 
	 * @return The thread in whose thread local Coordination stack this
	 *         Coordination has been pushed or {@code null} if this Coordination
	 *         is not in any thread local Coordination stack.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[ADMIN]} for this Coordination.
	 */
	Thread getThread();

	/**
	 * Returns the bundle that created this Coordination. This is the bundle
	 * that obtained the {@link Coordinator} service that was used to create
	 * this Coordination.
	 * 
	 * @return The bundle that created this Coordination.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[ADMIN]} for this Coordination.
	 */
	Bundle getBundle();

	/**
	 * Returns the Coordination enclosing this Coordination if this Coordination
	 * is on the thread local Coordination stack.
	 * 
	 * <p>
	 * When a Coordination is {@link #push() pushed} onto the thread local
	 * Coordination stack, the former {@link Coordinator#peek() current
	 * Coordination}, if any, is the enclosing Coordination of this
	 * Coordination. When this Coordination is {@link Coordinator#pop() removed}
	 * from the thread local Coordination stack, this Coordination no longer has
	 * an enclosing Coordination.
	 * 
	 * @return The Coordination enclosing this Coordination if this Coordination
	 *         is on the thread local Coordination stack or {@code null} if this
	 *         Coordination is not on the thread local Coordination stack or has
	 *         no enclosing Coordination.
	 * @throws SecurityException If the caller does not have
	 *         {@code CoordinationPermission[ADMIN]} for this Coordination.
	 */
	Coordination getEnclosingCoordination();
}
