#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.
#
from qpid.client import Client, Closed
from qpid.queue import Empty
from qpid.content import Content
from qpid.testlib import testrunner, TestBase

class QueueTests(TestBase):
    """Tests for 'methods' on the amqp queue 'class'"""

    def test_purge(self):
        """
        Test that the purge method removes messages from the queue
        """
        channel = self.channel
        #setup, declare a queue and add some messages to it:
        channel.exchange_declare(exchange="test-exchange", type="direct")
        channel.queue_declare(queue="test-queue", exclusive=True)
        channel.queue_bind(queue="test-queue", exchange="test-exchange", routing_key="key")
        channel.message_transfer(destination="test-exchange", routing_key="key", body="one")
        channel.message_transfer(destination="test-exchange", routing_key="key", body="two")
        channel.message_transfer(destination="test-exchange", routing_key="key", body="three")

        #check that the queue now reports 3 messages:
        reply = channel.queue_declare(queue="test-queue")
        self.assertEqual(3, reply.message_count)

        #now do the purge, then test that three messages are purged and the count drops to 0
        reply = channel.queue_purge(queue="test-queue");
        self.assertEqual(3, reply.message_count)        
        reply = channel.queue_declare(queue="test-queue")
        self.assertEqual(0, reply.message_count)

        #send a further message and consume it, ensuring that the other messages are really gone
        channel.message_transfer(destination="test-exchange", routing_key="key", body="four")
        channel.message_consume(queue="test-queue", destination="tag", no_ack=True)
        queue = self.client.queue("tag")
        msg = queue.get(timeout=1)
        self.assertEqual("four", msg.body)

        #check error conditions (use new channels): 
        channel = self.client.channel(2)
        channel.channel_open()
        try:
            #queue specified but doesn't exist:
            channel.queue_purge(queue="invalid-queue")
            self.fail("Expected failure when purging non-existent queue")
        except Closed, e:
            self.assertChannelException(404, e.args[0])

        channel = self.client.channel(3)
        channel.channel_open()
        try:
            #queue not specified and none previously declared for channel:
            channel.queue_purge()
            self.fail("Expected failure when purging unspecified queue")
        except Closed, e:
            self.assertConnectionException(530, e.args[0])

        #cleanup    
        other = self.connect()
        channel = other.channel(1)
        channel.channel_open()
        channel.exchange_delete(exchange="test-exchange")

    def test_declare_exclusive(self):
        """
        Test that the exclusive field is honoured in queue.declare
        """
        # TestBase.setUp has already opened channel(1)
        c1 = self.channel
        # Here we open a second separate connection:
        other = self.connect()
        c2 = other.channel(1)
        c2.channel_open()

        #declare an exclusive queue:
        c1.queue_declare(queue="exclusive-queue", exclusive="True")
        try:
            #other connection should not be allowed to declare this:
            c2.queue_declare(queue="exclusive-queue", exclusive="True")
            self.fail("Expected second exclusive queue_declare to raise a channel exception")
        except Closed, e:
            self.assertChannelException(405, e.args[0])


    def test_declare_passive(self):
        """
        Test that the passive field is honoured in queue.declare
        """
        channel = self.channel
        #declare an exclusive queue:
        channel.queue_declare(queue="passive-queue-1", exclusive="True")
        channel.queue_declare(queue="passive-queue-1", passive="True")
        try:
            #other connection should not be allowed to declare this:
            channel.queue_declare(queue="passive-queue-2", passive="True")
            self.fail("Expected passive declaration of non-existant queue to raise a channel exception")
        except Closed, e:
            self.assertChannelException(404, e.args[0])


    def test_bind(self):
        """
        Test various permutations of the queue.bind method
        """
        channel = self.channel
        channel.queue_declare(queue="queue-1", exclusive="True")

        #straightforward case, both exchange & queue exist so no errors expected:
        channel.queue_bind(queue="queue-1", exchange="amq.direct", routing_key="key1")

        #bind the default queue for the channel (i.e. last one declared):
        channel.queue_bind(exchange="amq.direct", routing_key="key2")

        #use the queue name where neither routing key nor queue are specified:
        channel.queue_bind(exchange="amq.direct")

        #try and bind to non-existant exchange
        try:
            channel.queue_bind(queue="queue-1", exchange="an-invalid-exchange", routing_key="key1")
            self.fail("Expected bind to non-existant exchange to fail")
        except Closed, e:
            self.assertChannelException(404, e.args[0])

        #need to reopen a channel:    
        channel = self.client.channel(2)
        channel.channel_open()

        #try and bind non-existant queue:
        try:
            channel.queue_bind(queue="queue-2", exchange="amq.direct", routing_key="key1")
            self.fail("Expected bind of non-existant queue to fail")
        except Closed, e:
            self.assertChannelException(404, e.args[0])

    def test_unbind_direct(self):
        self.unbind_test(exchange="amq.direct", routing_key="key")

    def test_unbind_topic(self):
        self.unbind_test(exchange="amq.topic", routing_key="key")

    def test_unbind_fanout(self):
        self.unbind_test(exchange="amq.fanout")

    def test_unbind_headers(self):
        self.unbind_test(exchange="amq.match", args={ "x-match":"all", "a":"b"}, headers={"a":"b"})

    def unbind_test(self, exchange, routing_key="", args=None, headers={}):
        #bind two queues and consume from them
        channel = self.channel
        
        channel.queue_declare(queue="queue-1", exclusive="True")
        channel.queue_declare(queue="queue-2", exclusive="True")

        channel.message_consume(queue="queue-1", destination="queue-1", no_ack=True)
        channel.message_consume(queue="queue-2", destination="queue-2", no_ack=True)

        queue1 = self.client.queue("queue-1")
        queue2 = self.client.queue("queue-2")

        channel.queue_bind(exchange=exchange, queue="queue-1", routing_key=routing_key, arguments=args)
        channel.queue_bind(exchange=exchange, queue="queue-2", routing_key=routing_key, arguments=args)

        #send a message that will match both bindings
        channel.message_transfer(destination=exchange, routing_key=routing_key, application_headers=headers, body="one")
        
        #unbind first queue
        channel.queue_unbind(exchange=exchange, queue="queue-1", routing_key=routing_key, arguments=args)
        
        #send another message
        channel.message_transfer(destination=exchange, routing_key=routing_key, application_headers=headers, body="two")

        #check one queue has both messages and the other has only one
        self.assertEquals("one", queue1.get(timeout=1).body)
        try:
            msg = queue1.get(timeout=1)
            self.fail("Got extra message: %s" % msg.body)
        except Empty: pass

        self.assertEquals("one", queue2.get(timeout=1).body)
        self.assertEquals("two", queue2.get(timeout=1).body)
        try:
            msg = queue2.get(timeout=1)
            self.fail("Got extra message: " + msg)
        except Empty: pass        


    def test_delete_simple(self):
        """
        Test core queue deletion behaviour
        """
        channel = self.channel

        #straight-forward case:
        channel.queue_declare(queue="delete-me")
        channel.message_transfer(routing_key="delete-me", body="a")
        channel.message_transfer(routing_key="delete-me", body="b")
        channel.message_transfer(routing_key="delete-me", body="c")        
        reply = channel.queue_delete(queue="delete-me")
        self.assertEqual(3, reply.message_count)
        #check that it has gone be declaring passively
        try:
            channel.queue_declare(queue="delete-me", passive="True")
            self.fail("Queue has not been deleted")
        except Closed, e:
            self.assertChannelException(404, e.args[0])

        #check attempted deletion of non-existant queue is handled correctly:    
        channel = self.client.channel(2)
        channel.channel_open()
        try:
            channel.queue_delete(queue="i-dont-exist", if_empty="True")
            self.fail("Expected delete of non-existant queue to fail")
        except Closed, e:
            self.assertChannelException(404, e.args[0])

        

    def test_delete_ifempty(self):
        """
        Test that if_empty field of queue_delete is honoured
        """
        channel = self.channel

        #create a queue and add a message to it (use default binding):
        channel.queue_declare(queue="delete-me-2")
        channel.queue_declare(queue="delete-me-2", passive="True")
        channel.message_transfer(routing_key="delete-me-2", body="message")

        #try to delete, but only if empty:
        try:
            channel.queue_delete(queue="delete-me-2", if_empty="True")
            self.fail("Expected delete if_empty to fail for non-empty queue")
        except Closed, e:
            self.assertChannelException(406, e.args[0])

        #need new channel now:    
        channel = self.client.channel(2)
        channel.channel_open()

        #empty queue:
        channel.message_consume(destination="consumer_tag", queue="delete-me-2", no_ack=True)
        queue = self.client.queue("consumer_tag")
        msg = queue.get(timeout=1)
        self.assertEqual("message", msg.body)
        channel.message_cancel(destination="consumer_tag")

        #retry deletion on empty queue:
        channel.queue_delete(queue="delete-me-2", if_empty="True")

        #check that it has gone by declaring passively:
        try:
            channel.queue_declare(queue="delete-me-2", passive="True")
            self.fail("Queue has not been deleted")
        except Closed, e:
            self.assertChannelException(404, e.args[0])
        
    def test_delete_ifunused(self):
        """
        Test that if_unused field of queue_delete is honoured
        """
        channel = self.channel

        #create a queue and register a consumer:
        channel.queue_declare(queue="delete-me-3")
        channel.queue_declare(queue="delete-me-3", passive="True")
        channel.message_consume(destination="consumer_tag", queue="delete-me-3", no_ack=True)

        #need new channel now:    
        channel2 = self.client.channel(2)
        channel2.channel_open()
        #try to delete, but only if empty:
        try:
            channel2.queue_delete(queue="delete-me-3", if_unused="True")
            self.fail("Expected delete if_unused to fail for queue with existing consumer")
        except Closed, e:
            self.assertChannelException(406, e.args[0])


        channel.message_cancel(destination="consumer_tag")    
        channel.queue_delete(queue="delete-me-3", if_unused="True")
        #check that it has gone by declaring passively:
        try:
            channel.queue_declare(queue="delete-me-3", passive="True")
            self.fail("Queue has not been deleted")
        except Closed, e:
            self.assertChannelException(404, e.args[0])


