/*
 * Created on Apr 22, 2004
 *
 * To change the template for this generated file go to
 * Window - Preferences - Java - Code Generation - Code and Comments
 */
package org.codehaus.activemq.service;

import java.util.Map;

import javax.jms.JMSException;

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;

/**
 * A manager of MessageContainer instances
 */
public interface MessageContainerManager extends Service {
    
    /**
     * Creates a destination.
     * @param dest
     * @throws JMSException
     *
     */
    public void createMessageContainer(ActiveMQDestination dest) throws JMSException;

    /**
     * Destroys a destination.
     * @param dest
     * @throws JMSException
     *
     */
    public void destroyMessageContainer(ActiveMQDestination dest) throws JMSException;
        
    /**
     * Returns an unmodifiable map, indexed by ActiveMQDestination, of all the {@link org.codehaus.activemq.service.MessageContainerAdmin}
     * objects available in this container
     * 
     * @return the Map
     * @throws JMSException
     */
    public Map getMessageContainerAdmins() throws JMSException;

    /**
     * Returns an unmodifiable map, indexed by String name, of all the {@link javax.jms.Destination}
     * objects available in this container
     *
     * @return
     */
    public Map getDestinations();

    /**
     * @param client
     * @param info
     * @throws JMSException
     */
    public abstract void addMessageConsumer(BrokerClient client, ConsumerInfo info) throws JMSException;

    /**
     * @param client
     * @param info
     * @throws JMSException
     */
    public abstract void removeMessageConsumer(BrokerClient client, ConsumerInfo info) throws JMSException;

    /**
     * Delete a durable subscriber
     *
     * @param clientId
     * @param subscriberName
     * @throws JMSException if the subscriber doesn't exist or is still active
     */
    public abstract void deleteSubscription(String clientId, String subscriberName) throws JMSException;

    /**
     * @param client
     * @param message
     * @throws JMSException
     */
    public abstract void sendMessage(BrokerClient client, ActiveMQMessage message) throws JMSException;

    /**
     * Acknowledge a message as being read and consumed by the Consumer
     *
     * @param client
     * @param ack
     * @throws JMSException
     */
    public abstract void acknowledgeMessage(BrokerClient client, MessageAck ack) throws JMSException;


    /**
     * Called after a rollback of a JMS transaction to redeliver the message to the consumers
     * dispatch queue
     *
     * @param client
     * @param ack
     * @throws JMSException
     */
    public void redeliverMessage(BrokerClient client, MessageAck ack) throws JMSException;

    /**
     * Poll for messages
     *
     * @throws JMSException
     */
    public abstract void poll() throws JMSException;


    /**
     * A hook when the transaction is about to be commited; so apply all outstanding commands to the
     * Journal if using a Journal (transaction log)
     *
     * @param client
     * @param transactionId
     * @throws JMSException
     */
    public void commitTransaction(BrokerClient client, String transactionId) throws JMSException;

    /**
     * A hook when the transaction is about to be rolled back; so discard all outstanding commands
     * that are pending to be written to the Journal
     *
     * @param client
     * @param transactionId
     */
    public void rollbackTransaction(BrokerClient client, String transactionId);

    /**
     * Allows the lookup of a specific named message container
     *
     * @param physicalName
     * @return the MessageContainer
     * @throws JMSException
     */
    public MessageContainer getContainer(String physicalName) throws JMSException;

    /**
     * This is a hook to notify the dispatcher for the clients subscription that
     * we have acknowledged a message within a transaction but before the commit - so
     * the message is not really being acknowledged here but this method is intended to be a hook
     * to let the dispatcher know that we can now send another message to the client.
     * <p/>
     * Without this hook, if we have a prefetch value of 1, we can never consume 2 messages
     * in a transaction, since the ack for the first message never arrives until the commit()
     * @param client
     * @param transactionId
     * @param ack
     * @throws JMSException
     */
    public void acknowledgeTransactedMessage(BrokerClient client, String transactionId, MessageAck ack) throws JMSException;
    
    /**
     * @return the DeadLetterPolicy for this Container Manager
     */
    public DeadLetterPolicy getDeadLetterPolicy();
    
    /**
     * Set the DeadLetterPolicy for this Container Manager
     * @param policy
     */
    public void setDeadLetterPolicy(DeadLetterPolicy policy);
}