package de.ugoe.cs.eventbench.models;

import java.io.Serializable;
import java.security.InvalidParameterException;
import java.util.Collection;
import java.util.List;

import de.ugoe.cs.eventbench.data.Event;

/**
 * <p>
 * This interface defines the functionalities provided by stochastic processes.
 * </p>
 * 
 * @author Steffen Herbold
 * @version 1.0
 */
public interface IStochasticProcess extends Serializable {

	/**
	 * <p>
	 * Returns the probability, that the next event is {@code symbol} given the
	 * last events are {@code context}. The last element of {@code context} is
	 * the most recent in the history, the first element is the oldest.
	 * </p>
	 * 
	 * @param context
	 *            recently observed symbols
	 * @param symbol
	 *            event for which the probability is calculated
	 * @return probabilty the {@code symbol} is the next event, given the last
	 *         events {@code context}
	 * @throws InvalidParameterException
	 *             thrown if context or symbol is null
	 */
	double getProbability(List<? extends Event<?>> context, Event<?> symbol);

	/**
	 * <p>
	 * Returns the probabilitiy that a given sequence is generated by the
	 * stochastic process.
	 * </p>
	 * 
	 * @param sequence
	 *            sequences of which the probability is calculated
	 * @return probability of the sequences; 1.0 if sequence is empty or null
	 * @throws InvalidParameterException
	 *             thrown if sequence is null
	 */
	double getProbability(List<? extends Event<?>> sequence);

	/**
	 * <p>
	 * Generates a random sequence of events. The sequence starts with
	 * {@link Event#STARTEVENT} and finishes with {@link Event#ENDEVENT}.
	 * </p>
	 * 
	 * @return randomly generated sequence
	 */
	public List<? extends Event<?>> randomSequence();

	/**
	 * <p>
	 * Generates a random sequence of events. The sequence starts with
	 * {@link Event#STARTEVENT} and finishes with
	 * <ul>
	 * <li>{@link Event#ENDEVENT} if validEnd==true.</li>
	 * <li>b) if a generated sequences reaches {@link Event#ENDEVENT} before
	 * maxLength, the sequence finishes and is shorter than maxLenght.
	 * Otherwise, the sequence finishes as soon as maxLength is reached and the
	 * final event of the sequence must not be {@link Event#ENDEVENT}.</li>
	 * </ul>
	 * </p>
	 * 
	 * @param maxLength
	 *            maximum length of the generated sequence
	 * @param validEnd
	 *            if true, only sequences that finish with
	 *            {@link Event#ENDEVENT} are generated
	 * @return randomly generated sequence
	 * 
	 */
	public List<? extends Event<?>> randomSequence(int maxLength,
			boolean validEnd);

	/**
	 * <p>
	 * Generates all sequences of a given length are possible, i.e., have a
	 * positive probability.<br>
	 * All states are used as possible starting states.
	 * </p>
	 * 
	 * @param length
	 *            length of the generated sequences
	 * @return generated sequences
	 * @see #generateSequences(int, boolean)
	 * @throws InvalidParameterException
	 *             thrown if length is less than or equal to 0
	 */
	public Collection<List<? extends Event<?>>> generateSequences(int length);

	/**
	 * <p>
	 * Generates all sequences of given length that can are possible, i.e., have
	 * positive probability.<br>
	 * If {@code fromStart==true}, all generated sequences start in
	 * {@link Event#STARTEVENT}. Otherwise this method is the same as
	 * {@link #generateSequences(int)}.
	 * </p>
	 * 
	 * @param length
	 *            length of the generated sequences
	 * @param fromStart
	 *            if true, all generated sequences start with
	 *            {@link Event#STARTEVENT}
	 * @return generated sequences
	 * @throws InvalidParameterException
	 *             thrown if length is less than or equal to 0
	 */
	public Collection<List<? extends Event<?>>> generateSequences(int length,
			boolean fromStart);

	/**
	 * <p>
	 * Generates all sequences starting with {@link Event#STARTEVENT} and
	 * finishing with {@link Event#ENDEVENT} of a given length. It is possible
	 * that no such sequence exists with the defined length and the returned set
	 * is empty. If {@code length} is less than 2 the returned set is always
	 * empty.
	 * </p>
	 * 
	 * @param length
	 * @return generated sequences
	 * @throws InvalidParameterException
	 *             thrown if length is less than or equal to 0
	 */
	public Collection<List<? extends Event<?>>> generateValidSequences(
			int length);

	/**
	 * <p>
	 * Returns the number of states known by the stochastic process, i.e., the
	 * size of its alphabet.
	 * </p>
	 * 
	 * @return number of states
	 */
	public int getNumSymbols();

	/**
	 * <p>
	 * Returns a string representation of all known states.
	 * </p>
	 * 
	 * @return string representation for all known states
	 */
	public String[] getSymbolStrings();

	/**
	 * <p>
	 * Returns the number of states the process would have if it would be
	 * flattened through state-splitting to a first-order Markov model.
	 * </p>
	 * <p>
	 * If it is not possible to flatten the model, -1 is returned.
	 * </p>
	 * 
	 * @return number of states an equivalent FOM would have; -1 if not
	 *         available
	 */
	public int getNumFOMStates();

	/**
	 * <p>
	 * Returns the number of transitions the process would have if it would be
	 * flattened through state-splitting to a first-order Markov model.
	 * </p>
	 * 
	 * @return number of transitions an equivalent FOM would have; -1 if not
	 *         available
	 */
	public int getNumTransitions();

	/**
	 * <p>
	 * Returns all states known by the stochastic process, i.e., its
	 * {@link Event}s.
	 * </p>
	 * 
	 * @return events known by the process
	 */
	public Collection<? extends Event<?>> getEvents();

}