/** 
 * 
 * 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.broker;

import org.codehaus.activemq.capacity.CapacityMonitor;
import org.codehaus.activemq.message.ActiveMQMessage;
import org.codehaus.activemq.message.ActiveMQXid;
import org.codehaus.activemq.message.ConnectionInfo;
import org.codehaus.activemq.message.ConsumerInfo;
import org.codehaus.activemq.message.MessageAck;
import org.codehaus.activemq.message.ProducerInfo;
import org.codehaus.activemq.security.SecurityAdapter;
import org.codehaus.activemq.service.DeadLetterPolicy;
import org.codehaus.activemq.service.MessageContainerManager;
import org.codehaus.activemq.service.Service;
import org.codehaus.activemq.service.RedeliveryPolicy;
import org.codehaus.activemq.store.PersistenceAdapter;

import javax.jms.JMSException;
import javax.naming.Context;
import javax.transaction.xa.XAException;
import java.io.File;
import java.util.Hashtable;
import java.util.Map;

/**
 * The Message Broker which routes messages,
 * maintains subscriptions and connections, acknowlegdges messages and handles
 * transactions.
 *
 * @version $Revision: 1.3 $
 */
public interface Broker extends Service, CapacityMonitor {
    
    /**
     * Get's the admin interface of the broker.
     * 
     * @return the admin interface of the broker.
     */
    public BrokerAdmin getBrokerAdmin();

    /**
     * Notification of a new client attempting to connect, which can
     * be rejected if authentication or authorization fails.
     */
    public void addClient(BrokerClient client, ConnectionInfo info) throws JMSException;

    /**
     * A hint to the broker that an BrokerClient has stopped
     * This enables the broker to clean-up any outstanding processing
     * that may be outstanding
     */
    public void removeClient(BrokerClient client, ConnectionInfo info) throws JMSException;

    /**
     * Adds a new message producer, which could be rejected due to authorization
     */
    public void addMessageProducer(BrokerClient client, ProducerInfo info) throws JMSException;

    /**
     * Removes a producer
     */
    public void removeMessageProducer(BrokerClient client, ProducerInfo info) throws JMSException;


    /**
     * Add an active message consumer, which could be rejected due to authorization
     */
    public void addMessageConsumer(BrokerClient client, ConsumerInfo info) throws JMSException;

    /**
     * remove an active message consumer
     */
    public void removeMessageConsumer(BrokerClient client, ConsumerInfo info) throws JMSException;


    /**
     * send a message to the broker
     */
    public void sendMessage(BrokerClient client, ActiveMQMessage message) throws JMSException;

    /**
     * send a message to the broker within a transaction
     */
    public void sendTransactedMessage(BrokerClient client, String transactionId, ActiveMQMessage message) throws JMSException;

    /**
     * Acknowledge positively or negatively, the consumption of a message by the Message Consumer
     */
    public void acknowledgeMessage(BrokerClient client, MessageAck ack) throws JMSException;

    /**
     * Acknowledge positively or negatively, the consumption of a message within a transaction
     */
    public void acknowledgeTransactedMessage(BrokerClient client, String transactionId, MessageAck ack) throws JMSException;

    /**
     * gets a list of all the prepared xa transactions.
     *
     * @param client
     */
    public ActiveMQXid[] getPreparedTransactions(BrokerClient client) throws XAException;


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

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

    /**
     * start a transaction
     *
     * @param client
     * @param transactionId
     */
    public void startTransaction(BrokerClient client, String transactionId) throws JMSException;

    /**
     * commit a transaction
     *
     * @param client
     * @param transactionId
     * @throws JMSException
     */
    public void commitTransaction(BrokerClient client, String transactionId) throws JMSException;

    /**
     * rollback a transaction
     *
     * @param client
     * @param transactionId
     * @throws JMSException
     */
    public void rollbackTransaction(BrokerClient client, String transactionId) throws JMSException;


    /**
     * @param client
     * @param xid
     * @throws XAException
     */
    public void startTransaction(BrokerClient client, ActiveMQXid xid) throws XAException;

    /**
     * @param client
     * @param xid
     * @return
     * @throws XAException
     */
    public int prepareTransaction(BrokerClient client, ActiveMQXid xid) throws XAException;

    /**
     * @param client
     * @param xid
     * @throws XAException
     */

    public void rollbackTransaction(BrokerClient client, ActiveMQXid xid) throws XAException;

    /**
     * @param client
     * @param xid
     * @param onePhase
     * @throws XAException
     */
    public void commitTransaction(BrokerClient client, ActiveMQXid xid, boolean onePhase) throws XAException;


    // Properties
    //-------------------------------------------------------------------------

    /**
     * Get a temp directory - used for spooling
     *
     * @return a File ptr to the directory
     */
    public File getTempDir();

    /**
     * @return the name of the Broker
     */
    public String getBrokerName();
    
    /**
     * @return the name of the cluster the broker belongs to
     */
    public String getBrokerClusterName();

    /**
     * @return the PersistenceAdaptor
     */
    public PersistenceAdapter getPersistenceAdapter();

    /**
     * set the persistence adaptor
     *
     * @param persistenceAdapter
     */
    public void setPersistenceAdapter(PersistenceAdapter persistenceAdapter);

    /**
     * @return a map, indexed by name of the container managers
     */
    public Map getContainerManagerMap();

    /**
     * Returns the naming context of the destinations available in this broker
     *
     * @param environment
     * @return the context
     */
    public Context getDestinationContext(Hashtable environment);

    /**
     * Add a ConsumerInfoListener to the Broker
     *
     * @param l
     */
    public void addConsumerInfoListener(ConsumerInfoListener l);

    /**
     * Remove a ConsumerInfoListener from the Broker
     *
     * @param l
     */
    public void removeConsumerInfoListener(ConsumerInfoListener l);


    /**
     * @return the MessageContainerManager for durable topics
     */
    public MessageContainerManager getPersistentTopicContainerManager();

    /**
     * @return the MessageContainerManager for transient topics
     */
    public MessageContainerManager getTransientTopicContainerManager();

    /**
     * @return the MessageContainerManager for persistent queues
     */
    public MessageContainerManager getPersistentQueueContainerManager();

    /**
     * @return the MessageContainerManager for transient queues
     */
    public MessageContainerManager getTransientQueueContainerManager();

    /**
     * Returns the security adapter used to authenticate and authorize access to JMS resources
     */
    public SecurityAdapter getSecurityAdapter();

    /**
     * Sets the security adapter used to authenticate and authorize access to JMS resources
     */
    public void setSecurityAdapter(SecurityAdapter securityAdapter);

    /**
     * @return the RedeliveryPolicy
     */
    RedeliveryPolicy getRedeliveryPolicy();

    /**
     * set the redelivery policy
     * @param redeliveryPolicy
     */
    void setRedeliveryPolicy(RedeliveryPolicy redeliveryPolicy);
    
    /**
     * @return the DeadLetterPolicy
     */
    public DeadLetterPolicy getDeadLetterPolicy();
    
    /**
     * set the dead letter policy
     * @param deadLetterPolicy
     */
    public void setDeadLetterPolicy(DeadLetterPolicy deadLetterPolicy);
    
    /**
     * Add a message to a dead letter queue
     * @param deadLetterName
     * @param message
     * @throws JMSException
     */
    public void sendToDeadLetterQueue(String deadLetterName,ActiveMQMessage message) throws JMSException;
   
}
