/*
 * Copyright 1999,2004-2005 The Apache Software Foundation.
 * 
 * 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.apache.catalina.tribes;

import java.io.Serializable;

/**
 * Channel interface<br>
 * A channel is a representation of a group of nodes all participating in some sort of
 * communication with each other.<br>
 * The channel is the main API class for Tribes, this is essentially the only class
 * that an application needs to be aware of. Through the channel the application can:<br>
 * 1. send messages<br>
 * 2. receive message (by registering a <code>ChannelListener</code><br>
 * 3. get all members of the group <code>getMembers()</code><br>
 * 4. receive notifications of members added and members disappeared by
 *    registerering a <code>MembershipListener</code><br>
 * <br>
 * The channel has 5 major components:<br>
 * 1. Data receiver, with a built in thread pool to receive messages from other peers<br>
 * 2. Data sender, an implementation for sending data using NIO or java.io<br>
 * 3. Membership listener,listens for membership broadcasts<br>
 * 4. Membership broadcaster, broadcasts membership pings.<br>
 * 5. Channel interceptors, the ability to manipulate messages as they are sent or arrive<br><br>
 * The channel layout is:
 * <pre><code>
 *  ChannelListener_1..ChannelListener_N MembershipListener_1..MembershipListener_N [Application Layer]
 *            \          \                  /                   /
 *             \          \                /                   /
 *              \          \              /                   /
 *               \          \            /                   /
 *                \          \          /                   /
 *                 \          \        /                   /
 *                  ---------------------------------------
 *                                  |
 *                                  |
 *                               Channel
 *                                  |
 *                         ChannelInterceptor_1
 *                                  |                                               [Channel stack]
 *                         ChannelInterceptor_N
 *                                  |
 *                             Coordinator (implements MessageListener,MembershipListener,ChannelInterceptor)
 *                          --------------------
 *                         /        |           \ 
 *                        /         |            \
 *                       /          |             \
 *                      /           |              \
 *                     /            |               \
 *           MembershipService ChannelSender ChannelReceiver                        [IO layer]
 * </code></pre>
 * 
 * For example usage @see org.apache.catalina.tribes.group.GroupChannel
 * @author Filip Hanik
 * @version $Revision: 304032 $, $Date: 2005-07-27 10:11:55 -0500 (Wed, 27 Jul 2005) $
 */
public interface Channel {
    
    /**
     * Start and stop sequences can be controlled by these constants
     * This allows you to start separate components of the channel <br>
     * DEFAULT - starts or stops all components in the channel
     * @see #start(int)
     * @see #stop(int)
     */
    public static final int DEFAULT = 15;

    /**
     * Start and stop sequences can be controlled by these constants
     * This allows you to start separate components of the channel <br>
     * SND_RX_SEQ - starts or stops the data receiver. Start means opening a server socket
     * in case of a TCP implementation
     * @see #start(int)
     * @see #stop(int)
     */
    public static final int SND_RX_SEQ = 1;

    /**
     * Start and stop sequences can be controlled by these constants
     * This allows you to start separate components of the channel <br>
     * SND_TX_SEQ - starts or stops the data sender. This should not open any sockets,
     * as sockets are opened on demand when a message is being sent
     * @see #start(int)
     * @see #stop(int)
     */
    public static final int SND_TX_SEQ = 2;

    /**
     * Start and stop sequences can be controlled by these constants
     * This allows you to start separate components of the channel <br>
     * MBR_RX_SEQ - starts or stops the membership listener. In a multicast implementation
     * this will open a datagram socket and join a group and listen for membership messages
     * members joining
     * @see #start(int)
     * @see #stop(int)
     */
    public static final int MBR_RX_SEQ = 4;

    /**
     * Start and stop sequences can be controlled by these constants
     * This allows you to start separate components of the channel <br>
     * MBR_TX_SEQ - starts or stops the membership broadcaster. In a multicast implementation
     * this will open a datagram socket and join a group and broadcast the local member information
     * @see #start(int)
     * @see #stop(int)
     */
    public static final int MBR_TX_SEQ = 8;
    
    /**
     * Send options, when a message is sent, it can have an option flag
     * to trigger certain behavior. Most flags are used to trigger channel interceptors
     * as the message passes through the channel stack. <br>
     * However, there are four default flags that every channel implementation must implement<br>
     * SEND_OPTIONS_BYTE_MESSAGE - The message is a pure byte message and no marshalling or unmarshalling will
     * be performed.<br>
     * 
     * @see #send(Member[], Serializable , int)
     * @see #send(Member[], Serializable, int, ErrorHandler)
     */
    public static final int SEND_OPTIONS_BYTE_MESSAGE = 0x0001;

    /**
     * Send options, when a message is sent, it can have an option flag
     * to trigger certain behavior. Most flags are used to trigger channel interceptors
     * as the message passes through the channel stack. <br>
     * However, there are four default flags that every channel implementation must implement<br>
     * SEND_OPTIONS_USE_ACK - Message is sent and an ACK is received when the message has been received by the recipient<br>
     * If no ack is received, the message is not considered successful<br>
     * @see #send(Member[], Serializable , int)
     * @see #send(Member[], Serializable, int, ErrorHandler)
     */
    public static final int SEND_OPTIONS_USE_ACK = 0x0002;

    /**
     * Send options, when a message is sent, it can have an option flag
     * to trigger certain behavior. Most flags are used to trigger channel interceptors
     * as the message passes through the channel stack. <br>
     * However, there are four default flags that every channel implementation must implement<br>
     * SEND_OPTIONS_SYNCHRONIZED_ACK - Message is sent and an ACK is received when the message has been received and 
     * processed by the recipient<br>
     * If no ack is received, the message is not considered successful<br>
     * @see #send(Member[], Serializable , int)
     * @see #send(Member[], Serializable, int, ErrorHandler)
     */
    public static final int SEND_OPTIONS_SYNCHRONIZED_ACK = 0x0004;
    
    /**
     * Send options, when a message is sent, it can have an option flag
     * to trigger certain behavior. Most flags are used to trigger channel interceptors
     * as the message passes through the channel stack. <br>
     * However, there are four default flags that every channel implementation must implement<br>
     * SEND_OPTIONS_ASYNCHRONOUS - Message is sent and an ACK is received when the message has been received and 
     * processed by the recipient<br>
     * If no ack is received, the message is not considered successful<br>
     * @see #send(Member[], Serializable , int)
     * @see #send(Member[], Serializable, int, ErrorHandler)
     */
    public static final int SEND_OPTIONS_ASYNCHRONOUS = 0x0008;
    

    /**
     * Send options, when a message is sent, it can have an option flag
     * to trigger certain behavior. Most flags are used to trigger channel interceptors
     * as the message passes through the channel stack. <br>
     * However, there are four default flags that every channel implementation must implement<br>
     * SEND_OPTIONS_DEFAULT - the default sending options, just a helper variable. <br>
     * The default is <code>int SEND_OPTIONS_DEFAULT = SEND_OPTIONS_USE_ACK;</code><br>
     * @see #SEND_OPTIONS_USE_ACK
     * @see #send(Member[], Serializable , int)
     * @see #send(Member[], Serializable, int, ErrorHandler)
     */
    public static final int SEND_OPTIONS_DEFAULT = SEND_OPTIONS_USE_ACK;

    
    /**
     * Adds an interceptor to the channel message chain.
     * @param interceptor ChannelInterceptor
     */
    public void addInterceptor(ChannelInterceptor interceptor);
    
    /**
     * Starts up the channel. This can be called multiple times for individual services to start
     * The svc parameter can be the logical or value of any constants
     * @param svc int value of <BR>
     * DEFAULT - will start all services <BR>
     * MBR_RX_SEQ - starts the membership receiver <BR>
     * MBR_TX_SEQ - starts the membership broadcaster <BR>
     * SND_TX_SEQ - starts the replication transmitter<BR>
     * SND_RX_SEQ - starts the replication receiver<BR>
     * <b>Note:</b> In order for the membership broadcaster to 
     * transmit the correct information, it has to be started after the replication receiver.
     * @throws ChannelException if a startup error occurs or the service is already started or an error occurs.
     */
    public void start(int svc) throws ChannelException;

    /**
     * Shuts down the channel. This can be called multiple times for individual services to shutdown
     * The svc parameter can be the logical or value of any constants
     * @param svc int value of <BR>
     * DEFAULT - will shutdown all services <BR>
     * MBR_RX_SEQ - stops the membership receiver <BR>
     * MBR_TX_SEQ - stops the membership broadcaster <BR>
     * SND_TX_SEQ - stops the replication transmitter<BR>
     * SND_RX_SEQ - stops the replication receiver<BR>
     * @throws ChannelException if a startup error occurs or the service is already stopped or an error occurs.
     */
    public void stop(int svc) throws ChannelException;    
    
    /**
     * Send a message to one or more members in the cluster
     * @param destination Member[] - the destinations, can not be null or zero length, the reason for that
     * is that a membership change can occur and at that time the application is uncertain what group the message
     * actually got sent to.
     * @param msg Serializable - the message to send, has to be serializable, or a <code>ByteMessage</code> to 
     * send a pure byte array
     * @param options int - sender options, see class documentation for each interceptor that is configured in order to trigger interceptors
     * @return a unique Id that identifies the message that is sent
     * @see ByteMessage
     * @see #SEND_OPTIONS_USE_ACK
     * @see #SEND_OPTIONS_ASYNCHRONOUS
     * @see #SEND_OPTIONS_SYNCHRONIZED_ACK
     */
    public UniqueId send(Member[] destination, Serializable msg, int options) throws ChannelException;

    /**
     * Send a message to one or more members in the cluster
     * @param destination Member[] - the destinations, null or zero length means all
     * @param msg ClusterMessage - the message to send
     * @param options int - sender options, see class documentation
     * @param handler ErrorHandler - handle errors through a callback, rather than throw it
     * @return a unique Id that identifies the message that is sent
     * @exception ChannelException - if a serialization error happens.
     */
    public UniqueId send(Member[] destination, Serializable msg, int options, ErrorHandler handler) throws ChannelException;
    
    /**
     * Sends a heart beat through the interceptor stacks
     * Use this method to alert interceptors and other components to 
     * clean up garbage, timed out messages etc.<br>
     * If you application has a background thread, then you can save one thread,
     * by configuring your channel to not use an internal heartbeat thread
     * and invoking this method.
     * @see #setHeartbeat(boolean)
     */
    public void heartbeat();
    
    /**
     * Enables or disables internal heartbeat.
     * @param enable boolean - default value is implementation specific
     * @see #heartbeat()
     */
    public void setHeartbeat(boolean enable);
    
    /**
     * Add a membership listener, will get notified when a new member joins, leaves or crashes
     * <br>If the membership listener implements the Heartbeat interface
     * the <code>heartbeat()</code> method will be invoked when the heartbeat runs on the channel
     * @param listener MembershipListener
     * @see MembershipListener
     */
    public void addMembershipListener(MembershipListener listener);
    
    /**
     * Add a channel listener, this is a callback object when messages are received
     * <br>If the channel listener implements the Heartbeat interface
     * the <code>heartbeat()</code> method will be invoked when the heartbeat runs on the channel
     * @param listener ChannelListener
     * @see ChannelListener
     * @see Heartbeat
     */
    public void addChannelListener(ChannelListener listener);

    /**
     * remove a membership listener, listeners are removed based on Object.hashCode and Object.equals
     * @param listener MembershipListener
     * @see MembershipListener
     */
    public void removeMembershipListener(MembershipListener listener);
    /**
     * remove a channel listener, listeners are removed based on Object.hashCode and Object.equals
     * @param listener ChannelListener
     * @see ChannelListener
     */
    public void removeChannelListener(ChannelListener listener);
    
    /**
     * Returns true if there are any members in the group,
     * this call is the same as <code>getMembers().length>0</code>
     * @return boolean - true if there are any members automatically discovered
     */
    public boolean hasMembers() ;

    /**
     * Get all current group members
     * @return all members or empty array, never null 
     */
    public Member[] getMembers() ;

    /**
     * Return the member that represents this node. This is also the data
     * that gets broadcasted through the membership broadcaster component
     * @param incAlive - optimization, true if you want it to calculate alive time
     * since the membership service started.
     * @return Member
     */
    public Member getLocalMember(boolean incAlive);
    
    /**
     * Returns the member from the membership service with complete and 
     * recent data. Some implementations might serialize and send 
     * membership information along with a message, and instead of sending
     * complete membership details, only send the primary identifier for the member
     * but not the payload or other information. When such message is received
     * the application can retrieve the cached member through this call.<br>
     * In most cases, this is not necessary.
     * @param mbr Member
     * @return Member
     */
    public Member getMember(Member mbr);

    
}
