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

import junit.framework.TestCase;
import junit.textui.TestRunner;

import java.util.List;

public class ActiveMQDestinationTest extends TestCase {
    ActiveMQDestination topic1 = new ActiveMQTopic("FOO.BAR");
    ActiveMQDestination topic2 = new ActiveMQTopic("FOO.XXX");
    ActiveMQDestination topic3 = new ActiveMQTopic("FOO.BAR");
    ActiveMQDestination topic4 = new ActiveMQTopic(null);

    ActiveMQDestination queue1 = new ActiveMQQueue("FOO.BAR");
    ActiveMQDestination queue2 = new ActiveMQQueue("FOO.XXX");
    ActiveMQDestination queue3 = new ActiveMQQueue("FOO.BAR");
    ActiveMQDestination queue4 = new ActiveMQQueue(null);


    public static void main(String[] args) {
        TestRunner.run(ActiveMQDestinationTest.class);
    }

    public void testCompareTopics() {
        assertCompareTo(topic1, topic2, -1);
        assertCompareTo(topic2, topic1, 1);
        assertCompareTo(topic1, topic3, 0);
        assertCompareTo(topic4, topic1, -1);
        assertCompareTo(topic1, topic4, 1);
    }

    public void testCompareQueues() {
        assertCompareTo(queue1, queue2, -1);
        assertCompareTo(queue2, queue1, 1);
        assertCompareTo(queue1, queue3, 0);
        assertCompareTo(queue4, queue1, -1);
        assertCompareTo(queue1, queue4, 1);
    }

    public void testCompareQueuesAndTopics() {
        assertCompareTo(topic1, queue1, 1);
        assertCompareTo(queue1, topic1, -1);
        assertCompareTo(topic1, queue2, -1);
        assertCompareTo(queue2, topic1, 1);
    }

    public void testGetClientID() {
        String clientID = "TestClientId";
        String temp = ActiveMQDestination.createTemporaryName(clientID);
        ActiveMQDestination tempDest = new ActiveMQTemporaryTopic(temp);
        assertTrue(ActiveMQDestination.getClientId(tempDest).equals(clientID));
    }

    public void testCompositeQueues() {
        ActiveMQDestination destination = new ActiveMQQueue("FOO.BAR,COM.ACME.WHATNOT,FOO.>");
        assertTrue(destination.isComposite());

        List destinations = destination.getChildDestinations();
        assertEquals("Size is wrong", 3, destinations.size());

        assertEquals(new ActiveMQQueue("FOO.BAR"), destinations.get(0));
        assertEquals(new ActiveMQQueue("COM.ACME.WHATNOT"), destinations.get(1));
        assertEquals(new ActiveMQQueue("FOO.>"), destinations.get(2));

    }

    public void testCompositeQueueWithChildTopic() {
        ActiveMQDestination destination = new ActiveMQQueue("FOO.BAR,topic://COM.ACME.WHATNOT,FOO.>");
        assertTrue(destination.isComposite());

        List destinations = destination.getChildDestinations();
        assertEquals("Size is wrong", 3, destinations.size());

        assertEquals(new ActiveMQQueue("FOO.BAR"), destinations.get(0));
        assertEquals(new ActiveMQTopic("COM.ACME.WHATNOT"), destinations.get(1));
        assertEquals(new ActiveMQQueue("FOO.>"), destinations.get(2));

    }

    public void testCompositeTopics() {
        ActiveMQDestination destination = new ActiveMQTopic("FOO.BAR,COM.ACME.WHATNOT,FOO.>");
        assertTrue(destination.isComposite());

        List destinations = destination.getChildDestinations();
        assertEquals("Size is wrong", 3, destinations.size());

        assertEquals(new ActiveMQTopic("FOO.BAR"), destinations.get(0));
        assertEquals(new ActiveMQTopic("COM.ACME.WHATNOT"), destinations.get(1));
        assertEquals(new ActiveMQTopic("FOO.>"), destinations.get(2));

    }

    public void testCompositeTopicsWithChildQueue() {
        ActiveMQDestination destination = new ActiveMQTopic("queue://FOO.BAR,COM.ACME.WHATNOT,queue://FOO.>");
        assertTrue(destination.isComposite());

        List destinations = destination.getChildDestinations();
        assertEquals("Size is wrong", 3, destinations.size());

        assertEquals(new ActiveMQQueue("FOO.BAR"), destinations.get(0));
        assertEquals(new ActiveMQTopic("COM.ACME.WHATNOT"), destinations.get(1));
        assertEquals(new ActiveMQQueue("FOO.>"), destinations.get(2));

    }

    public void testNormalDestinationsAreNotComposite() {
        ActiveMQDestination destination = new ActiveMQQueue("FOO");
        assertTrue(!destination.isComposite());

        destination = new ActiveMQTopic("FOO");
        assertTrue(!destination.isComposite());

        System.out.println("Composite queues: " + destination.getChildDestinations());
    }
    
    public void testAdvisoryDestination(){ 
        String name = "foo.bar";
        ActiveMQDestination destination = new ActiveMQTopic(name);
        ActiveMQDestination advisory = destination.getTopicForConsumerAdvisory();
        assertTrue(advisory.isAdvisory());
    }

    protected void assertCompareTo(ActiveMQDestination dest1, ActiveMQDestination dest2, int expected) {
        int value = dest1.compareTo(dest2);
        String message = "Comparsing: " + dest1 + " to: " + dest2 + " found value: " + value + " expected: " + expected;
        String hashCodeMessage = "HashCode for: " + dest1 + " is " + dest1.hashCode() + " for: " + dest2 + " is " + dest2.hashCode();

        // asserting different hash codes is a bit naughty as they could be equal on a different JVM maybe
        switch (expected) {
            case 0:
                assertEquals(message, 0, value);
                assertEquals(hashCodeMessage, dest1.hashCode(), dest2.hashCode());
                break;
            case 1:
                assertTrue(message, value > 0);
                assertTrue(hashCodeMessage, dest1.hashCode() != dest2.hashCode());
                break;
            default:
                assertTrue(message, value < 0);
                assertTrue(hashCodeMessage, dest1.hashCode() != dest2.hashCode());

        }
    }

}
