/*
 * Copyright (c) OSGi Alliance (2008, 2009). 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.blueprint.container;

import org.osgi.framework.Bundle;

/**
 * A Blueprint Event.
 *
 * <p>
 * <code>BlueprintEvent</code> objects are delivered to all registered
 * {@link BlueprintListener} services. Blueprint Events must be asynchronously
 * delivered in chronological order with respect to each listener.
 *
 * <p>
 * In addition, after a Blueprint Listener is registered, the Blueprint extender
 * will synchronously send to this Blueprint Listener the last Blueprint Event
 * for each ready Blueprint bundle managed by this extender. This
 * <em>replay</em> of Blueprint Events is designed so that the new Blueprint
 * Listener can be informed of the state of each Blueprint bundle. Blueprint
 * Events sent during this replay will have the {@link #isReplay()} flag set.
 * The Blueprint extender must ensure that this replay phase does not interfere
 * with new Blueprint Events so that the chronological order of all Blueprint
 * Events received by the Blueprint Listener is preserved. If the last Blueprint
 * Event for a given Blueprint bundle is {@link #DESTROYED}, the extender must
 * not send it during this replay phase.
 *
 * <p>
 * A type code is used to identify the type of event. The following event types
 * are defined:
 * <ul>
 * <li>{@link #CREATING}</li>
 * <li>{@link #CREATED}</li>
 * <li>{@link #DESTROYING}</li>
 * <li>{@link #DESTROYED}</li>
 * <li>{@link #FAILURE}</li>
 * <li>{@link #GRACE_PERIOD}</li>
 * <li>{@link #WAITING}</li>
 * </ul>
 *
 * <p>
 * In addition to calling the registered {@link BlueprintListener} services, the
 * Blueprint extender must also send those events to the Event Admin service, if
 * it is available.
 *
 * @see BlueprintListener
 * @see EventConstants
 * @Immutable
 * @version $Revision: 1071714 $
 */
public class BlueprintEvent {

	/**
	 * The Blueprint extender has started creating a Blueprint Container for the
	 * bundle.
	 */
	public static final int	CREATING		= 1;
	/**
	 * The Blueprint extender has created a Blueprint Container for the bundle.
	 * This event is sent after the Blueprint Container has been registered as a
	 * service.
	 */
	public static final int	CREATED			= 2;
	/**
	 * The Blueprint extender has started destroying the Blueprint Container for
	 * the bundle.
	 */
	public static final int	DESTROYING		= 3;
	/**
	 * The Blueprint Container for the bundle has been completely destroyed.
	 * This event is sent after the Blueprint Container has been unregistered as
	 * a service.
	 */
	public static final int	DESTROYED		= 4;
	/**
	 * The Blueprint Container creation for the bundle has failed. If this event
	 * is sent after a timeout in the Grace Period, the
	 * {@link #getDependencies()} method must return an array of missing
	 * mandatory dependencies. The event must also contain the cause of the
	 * failure as a <code>Throwable</code> through the {@link #getCause()}
	 * method.
	 */
	public static final int	FAILURE			= 5;
	/**
	 * The Blueprint Container has entered the grace period. The list of missing
	 * dependencies must be made available through the
	 * {@link #getDependencies()} method. During the grace period, a
	 * {@link #GRACE_PERIOD} event is sent each time the set of unsatisfied
	 * dependencies changes.
	 */
	public static final int	GRACE_PERIOD	= 6;
	/**
	 * The Blueprint Container is waiting on the availability of a service to
	 * satisfy an invocation on a referenced service. The missing dependency
	 * must be made available through the {@link #getDependencies()} method
	 * which will return an array containing one filter object as a String.
	 */
	public static final int	WAITING			= 7;

	/**
	 * Type of this event.
	 *
	 * @see #getType()
	 */
	private final int		type;
	/**
	 * The time when the event occurred.
	 *
	 * @see #getTimestamp()
	 */
	private final long		timestamp;
	/**
	 * The Blueprint bundle.
	 *
	 * @see #getBundle()
	 */
	private final Bundle	bundle;
	/**
	 * The Blueprint extender bundle.
	 *
	 * @see #getExtenderBundle()
	 */
	private final Bundle	extenderBundle;
	/**
	 * An array containing filters identifying the missing dependencies. Must
	 * not be <code>null</code> when the event type requires it.
	 *
	 * @see #getDependencies()
	 */
	private final String[]	dependencies;
	/**
	 * Cause of the failure.
	 *
	 * @see #getCause()
	 */
	private final Throwable	cause;
	/**
	 * Indicate if this event is a replay event or not.
	 *
	 * @see #isReplay()
	 */
	private final boolean	replay;

	/**
	 * Create a simple <code>BlueprintEvent</code> object.
	 *
	 * @param type The type of this event.
	 * @param bundle The Blueprint bundle associated with this event. This
	 *        parameter must not be <code>null</code>.
	 * @param extenderBundle The Blueprint extender bundle that is generating
	 *        this event. This parameter must not be <code>null</code>.
	 */
	public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle) {
		this(type, bundle, extenderBundle, null, null);
	}

	/**
	 * Create a <code>BlueprintEvent</code> object associated with a set of
	 * dependencies.
	 *
	 * @param type The type of this event.
	 * @param bundle The Blueprint bundle associated with this event. This
	 *        parameter must not be <code>null</code>.
	 * @param extenderBundle The Blueprint extender bundle that is generating
	 *        this event. This parameter must not be <code>null</code>.
	 * @param dependencies An array of <code>String</code> filters for each
	 *        dependency associated with this event. Must be a non-empty array
	 *        for event types {@link #FAILURE}, {@link #GRACE_PERIOD} and
	 *        {@link #WAITING}. Must be <code>null</code> for other event types.
	 */
	public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
			String[] dependencies) {
		this(type, bundle, extenderBundle, dependencies, null);
	}

	/**
	 * Create a <code>BlueprintEvent</code> object associated with a failure
	 * cause.
	 *
	 * @param type The type of this event.
	 * @param bundle The Blueprint bundle associated with this event. This
	 *        parameter must not be <code>null</code>.
	 * @param extenderBundle The Blueprint extender bundle that is generating
	 *        this event. This parameter must not be <code>null</code>.
	 * @param cause A <code>Throwable</code> object describing the root cause of
	 *        the event. May be <code>null</code>.
	 */
	public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
			Throwable cause) {
		this(type, bundle, extenderBundle, null, cause);
	}

	/**
	 * Create a <code>BlueprintEvent</code> object associated with a failure
	 * cause and a set of dependencies.
	 *
	 * @param type The type of this event.
	 * @param bundle The Blueprint bundle associated with this event. This
	 *        parameter must not be <code>null</code>.
	 * @param extenderBundle The Blueprint extender bundle that is generating
	 *        this event. This parameter must not be <code>null</code>.
	 * @param dependencies An array of <code>String</code> filters for each
	 *        dependency associated with this event. Must be a non-empty array
	 *        for event types {@link #GRACE_PERIOD} and	(@link #WAITING}.  It
	 *        is optional for {@link #FAILURE} event types.
	 *        Must be <code>null</code> for other event types.
	 * @param cause A <code>Throwable</code> object describing the root cause of
	 *        this event. May be <code>null</code>.
	 */
	public BlueprintEvent(int type, Bundle bundle, Bundle extenderBundle,
			String[] dependencies, Throwable cause) {
		this.type = type;
		this.timestamp = System.currentTimeMillis();
		this.bundle = bundle;
		this.extenderBundle = extenderBundle;
	    this.dependencies = dependencies == null ? null
                        : (String[]) dependencies.clone();;
		this.cause = cause;
		this.replay = false;
		if (bundle == null) {
			throw new NullPointerException("bundle must not be null");
		}
		if (extenderBundle == null) {
			throw new NullPointerException("extenderBundle must not be null");
		}
		switch (type) {
			case WAITING :
			case GRACE_PERIOD :
				if (dependencies == null) {
					throw new NullPointerException(
							"dependencies must not be null");
				}
				if (dependencies.length == 0) {
					throw new IllegalArgumentException(
							"dependencies must not be length zero");
				}
				break;
			case FAILURE :
				// not all FAILURE events have a dependency list, but if there
				// is one, it must be non-empty.
				if (dependencies != null) {
     				if (dependencies.length == 0) {
     					throw new IllegalArgumentException(
     							"dependencies must not be length zero");
     				}
				}
				break;
			default :
				if (dependencies != null) {
					throw new IllegalArgumentException(
							"dependencies must be null");
				}
				break;
		}
	}

	/**
	 * Create a new <code>BlueprintEvent</code> from the specified
	 * <code>BlueprintEvent</code>. The <code>timestamp</code> property will be
	 * copied from the original event and only the replay property will be
	 * overridden with the given value.
	 *
	 * @param event The original <code>BlueprintEvent</code> to copy. Must not
	 *        be <code>null</code>.
	 * @param replay <code>true</code> if this event should be used as a replay
	 *        event.
	 */
	public BlueprintEvent(BlueprintEvent event, boolean replay) {
		this.type = event.type;
		this.timestamp = event.timestamp;
		this.bundle = event.bundle;
		this.extenderBundle = event.extenderBundle;
		this.dependencies = event.dependencies;
		this.cause = event.cause;
		this.replay = replay;
	}

	/**
	 * Return the type of this event.
	 * <p>
	 * The type values are:
	 * <ul>
	 * <li>{@link #CREATING}</li>
	 * <li>{@link #CREATED}</li>
	 * <li>{@link #DESTROYING}</li>
	 * <li>{@link #DESTROYED}</li>
	 * <li>{@link #FAILURE}</li>
	 * <li>{@link #GRACE_PERIOD}</li>
	 * <li>{@link #WAITING}</li>
	 * </ul>
	 *
	 * @return The type of this event.
	 */
	public int getType() {
		return type;
	}

	/**
	 * Return the time at which this event was created.
	 *
	 * @return The time at which this event was created.
	 */
	public long getTimestamp() {
		return timestamp;
	}

	/**
	 * Return the Blueprint bundle associated with this event.
	 *
	 * @return The Blueprint bundle associated with this event.
	 */
	public Bundle getBundle() {
		return bundle;
	}

	/**
	 * Return the Blueprint extender bundle that is generating this event.
	 *
	 * @return The Blueprint extender bundle that is generating this event.
	 */
	public Bundle getExtenderBundle() {
		return extenderBundle;
	}

	/**
	 * Return the filters identifying the missing dependencies that caused this
	 * event.
	 *
	 * @return The filters identifying the missing dependencies that caused this
	 *         event if the event type is one of {@link #WAITING},
	 *         {@link #GRACE_PERIOD} or {@link #FAILURE} or <code>null</code>
	 *         for the other event types.
	 */
	public String[] getDependencies() {
		return dependencies == null ? null : (String[]) dependencies.clone();
	}

	/**
	 * Return the cause for this {@link #FAILURE} event.
	 *
	 * @return The cause of the failure for this event. May be <code>null</code>
	 *         .
	 */
	public Throwable getCause() {
		return cause;
	}

	/**
	 * Return whether this event is a replay event.
	 *
	 * @return <code>true</code> if this event is a replay event and
	 *         <code>false</code> otherwise.
	 */
	public boolean isReplay() {
		return replay;
	}
}
