package org.mockejb.jms.test;

import junit.framework.TestCase;
import java.util.Enumeration;
import javax.jms.*;

import org.mockejb.jms.MockQueue;

/**
 * Common class for testing messages.
 * Sets header and properties and "later" checks if
 * values are still the same.
 * Also tests if arbitrary message has header and properties
 * matching the test values.
 * @author Dimitar Gospodinov
 */
class MessageTester extends TestCase {

    protected Message message;
    
    private String jmsCorrelationId;
    private int jmsDeliveryMode;
    private Destination jmsDestination;
    private Destination jmsReplyTo;
    private long jmsExpiration;
    private String jmsMessageId;
    private int jmsPriority;
    private long jmsTimestamp;
    private String jmsType;

    protected MessageTester(String name) {
        super(name);
    }

    protected void tearDown() throws Exception {
        message = null;
        jmsCorrelationId = null;
        jmsDeliveryMode = 0;
        jmsDestination = null;
        jmsReplyTo = null;
        jmsExpiration = 0;
        jmsMessageId = null;
        jmsPriority = 0;
        jmsTimestamp = 0;
        jmsType = null;
    }

    protected void setUp() throws Exception {
        jmsCorrelationId = "xxx::CorrID";
        jmsDeliveryMode = DeliveryMode.NON_PERSISTENT;
        jmsDestination = new MockQueue("xxx::Destination");
        jmsReplyTo = new MockQueue("xxx::ReplyToDestination");
        jmsExpiration = 778899;
        jmsMessageId = "xxx::messageID";
        jmsPriority = 7;
        jmsTimestamp = 88889999;
        jmsType = "xxx::Type";
    
        message.setJMSCorrelationID(jmsCorrelationId);
        message.setJMSDeliveryMode(jmsDeliveryMode);
        message.setJMSDestination(jmsDestination);
        message.setJMSReplyTo(jmsReplyTo);
        message.setJMSExpiration(jmsExpiration);
        message.setJMSMessageID(jmsMessageId);
        message.setJMSPriority(jmsPriority);
        message.setJMSTimestamp(jmsTimestamp);
        message.setJMSType(jmsType);

        message.setBooleanProperty("boolean", false);
        message.setByteProperty("byte", (byte) 64);
        message.setShortProperty("short", (short) 1024);
        message.setIntProperty("int", 65540);
        message.setLongProperty("long", 58889999655511L);
        message.setFloatProperty("float", (float) 8822.8);
        message.setDoubleProperty("double", -1.88881E-221);
        message.setStringProperty("string", "xxx::str_val");
        Object obj = Integer.valueOf("70000");
        message.setObjectProperty("obj", obj);
        message.setBooleanProperty("boolean1", true);
    }

    protected void checkMessageAttributes() throws JMSException {
        checkMessageAttributes(message);
    }

    protected void checkMessageAttributes(Message message) throws JMSException {
        assertEquals(jmsCorrelationId, message.getJMSCorrelationID());
        assertEquals(jmsDeliveryMode, message.getJMSDeliveryMode());
        assertSame(jmsDestination, message.getJMSDestination());
        assertEquals(jmsExpiration, message.getJMSExpiration());
        assertEquals(jmsMessageId, message.getJMSMessageID());
        assertEquals(jmsPriority, message.getJMSPriority());
        assertSame(jmsReplyTo, message.getJMSReplyTo());
        assertEquals(jmsTimestamp, message.getJMSTimestamp());
        assertEquals(jmsType, message.getJMSType());
        assertFalse(message.getJMSRedelivered());

        Enumeration e = message.getPropertyNames();
        int i = 0;
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            if (name.equals("boolean")) {
                assertFalse(message.getBooleanProperty("boolean"));
            } else if (name.equals("byte")) {
                assertEquals(message.getByteProperty("byte"), (byte) 64);
            } else if (name.equals("short")) {
                assertEquals(message.getShortProperty("short"), (short) 1024);
            } else if (name.equals("int")) {
                assertEquals(message.getIntProperty("int"), 65540);
            } else if (name.equals("long")) {
                assertEquals(message.getLongProperty("long"), 58889999655511L);
            } else if (name.equals("float")) {
                assertEquals(
                    message.getFloatProperty("float"),
                    (float) 8822.8,
                    (float) 0.1);
            } else if (name.equals("double")) {
                assertEquals(
                    message.getDoubleProperty("double"),
                    -1.88881E-221,
                    0.00001E-221);
            } else if (name.equals("string")) {
                assertEquals(message.getStringProperty("string"), "xxx::str_val");
            } else if (name.equals("obj")) {
                assertTrue(message.getObjectProperty("obj") instanceof Integer);
                assertEquals(
                    ((Integer) message.getObjectProperty("obj")).intValue(),
                    70000);
            } else if (name.equals("boolean1")) {
                assertTrue(message.getBooleanProperty("boolean1"));
            } else {
                fail();
            }
            i++;
        }
        assertEquals(i, 10);
    }
}