/** 
 * 
 * Copyright 2004 Protique Ltd
 * 
 * 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.codehaus.activemq.service;

import org.codehaus.activemq.broker.BrokerClient;
import org.codehaus.activemq.message.ActiveMQDestination;
import org.codehaus.activemq.message.ActiveMQMessage;
import org.codehaus.activemq.message.ConsumerInfo;
import org.codehaus.activemq.message.MessageAck;

import javax.jms.JMSException;


/**
 * A Subscription holds messages to be dispatched to a a Client Consumer
 *
 * @version $Revision: 1.1 $
 */
public interface Subscription {


    /**
     * Set the active consumer info
     * @param client
     *
     * @param info
     */
    public void setActiveConsumer(BrokerClient client,ConsumerInfo info);

    /**
     * Called when the Subscription is discarded
     *
     * @throws JMSException
     */
    public void clear() throws JMSException;

    /**
     * Called when an active message consumer has closed.
     *
     * @throws JMSException
     */

    public void reset() throws JMSException;

    /**
     * @return Returns the clientId.
     */
    public String getClientId();

    /**
     * @return Returns the subscriberName.
     */
    public String getSubscriberName();

    /**
     * @return Returns the destination.
     */
    public ActiveMQDestination getDestination();

    /**
     * @return Returns the selector.
     */
    public String getSelector();

    /**
     * @return Returns true if an active message consumer is associated with this
     */
    public boolean isActive();

    /**
     * set the state of the Subscription
     *
     * @param newActive
     */
    public void setActive(boolean newActive) throws JMSException;

    /**
     * @return Returns the consumerNumber.
     */
    public int getConsumerNumber();

    /**
     * @return the consumer Id for the active consumer
     */
    public String getConsumerId();

    /**
     * determines if the Subscription is interested in the message
     *
     * @param message
     * @return
     * @throws JMSException
     */
    public boolean isTarget(ActiveMQMessage message) throws JMSException;


    /**
     * If the Subscription is a target for the message, the subscription will add a reference to
     * the message and register an interest in the message to the container
     *
     * @param container
     * @param message
     * @throws JMSException
     */

    public void addMessage(MessageContainer container, ActiveMQMessage message) throws JMSException;

    /**
     * Indicates a message has been delivered to a MessageConsumer
     * which is typically called for topic based subscriptions
     *
     * @param ack
     * @throws JMSException
     */

    public void messageConsumed(MessageAck ack) throws JMSException;

    /**
     * Forces the given message to be redelivered
     *
     * @param container
     * @param ack
     */
    public void redeliverMessage(MessageContainer container, MessageAck ack) throws JMSException;

    /**
     * Retrieve messages to dispatch
     *
     * @return
     * @throws JMSException
     */

    public ActiveMQMessage[] getMessagesToDispatch() throws JMSException;

    /**
     * Indicates if this Subscription has more messages to send to the
     * Consumer
     *
     * @return true if more messages available to dispatch
     * @throws JMSException
     */
    public boolean isReadyToDispatch() throws JMSException;

    /**
     * Indicates the Subscription it's reached it's pre-fetch limit
     *
     * @return true/false
     * @throws JMSException
     */
    public boolean isAtPrefetchLimit() throws JMSException;


    /**
     * Indicates the Consumer is a Durable Subscriber
     *
     * @return
     * @throws JMSException
     */
    public boolean isDurableTopic() throws JMSException;

    /**
     * Indicates the consumer is a browser only
     *
     * @return true if a Browser
     * @throws JMSException
     */
    public boolean isBrowser() throws JMSException;


    /**
     * Retreives the messageIdentity of the last message sent to this
     * Queue based Subscription
     *
     * @return the messageId of the last message or null
     * @throws JMSException
     */
    public MessageIdentity getLastMessageIdentity() throws JMSException;


    /**
     * Used for a Queue based Subscription to set the last acknowledged
     * message ID
     *
     * @param messageIdentity
     * @throws JMSException
     */
    public void setLastMessageIdentifier(MessageIdentity messageIdentity) throws JMSException;


    public boolean isWildcard();

    /**
     * Returns the persistent key used to uniquely identify this durable topic subscription
     *
     * @return
     */
    public String getPersistentKey();

    /**
     * Checks if this subscription is a duplicate durable subscription of the given consumer info
     *
     * @param info
     * @return true if this subscription is a durable topic subscription and the clientID and consumer
     *         names match
     */
    public boolean isSameDurableSubscription(ConsumerInfo info) throws JMSException;

    /**
     * We have not yet committed and so the message acknowledgement has not really occurred yet
     * but we need to let the dispatcher know that we can commence dispatching more messages
     * to the client. This is so that we can have a prefetch value of 1 yet we can still consume
     * 1000 messages inside a transaction, with all the acks coming after the commit() on the client.
     *
     * @param ack
     */
    public void onAcknowledgeTransactedMessageBeforeCommit(MessageAck ack) throws JMSException;

    /**
     * Lazily creates the persistent entry representation of this subscription
     */
    public SubscriberEntry getSubscriptionEntry();
}
