/*
 * Copyright 2016 Red Hat, Inc.
 *
 * Red Hat 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.
 */
package org.jbosson.plugins.fuse;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ActiveMQSession;
import org.apache.activemq.BlobMessage;
import org.apache.activemq.util.IndentPrinter;

import javax.jms.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.URL;
import java.util.Arrays;

/**
 * A simple tool for publishing messages of different types to test Destination.browse
 */
public class ProducerTool {

    private static final String TEST_MESSAGE = "This is a test message!";

    private Destination destination;

    private boolean topic = false;
    private String user = ActiveMQConnection.DEFAULT_USER;
    private String password = ActiveMQConnection.DEFAULT_PASSWORD;
    private String url = ActiveMQConnection.DEFAULT_BROKER_URL;
    private String subject = "TEST.BROWSE";

    public static void main(String[] args) {
        ProducerTool producerTool = new ProducerTool();
        String[] unknown = CommandLineSupport.setOptions(producerTool, args);
        if (unknown.length > 0) {
            System.out.println("Unknown options: " + Arrays.toString(unknown));
            System.exit(-1);
        }
        producerTool.showParameters();
        producerTool.sendMessages();
    }

    public void showParameters() {
        System.out.println("Connecting to URL: " + url + " (" + user + ":" + password + ")");
        System.out.println("Publishing Messages to " + (topic ? "topic" : "queue") + ": " + subject);
    }

    public void sendMessages() {
        ActiveMQConnection connection = null;
        try {
            // Create the connection.
            ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, password, url);
            connection = (ActiveMQConnection) connectionFactory.createConnection();
            connection.start();

            // Create the session
            ActiveMQSession session = (ActiveMQSession) connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            if (topic) {
                destination = session.createTopic(subject);
            } else {
                destination = session.createQueue(subject);
            }

            // Create the producer.
            MessageProducer producer = session.createProducer(destination);
            producer.setDeliveryMode(DeliveryMode.PERSISTENT);

            // text message
            Message message = session.createTextMessage(TEST_MESSAGE);
            sendMessage(message, producer);

            // url blob message
            message = session.createBlobMessage(new URL("http://test"));
            ((BlobMessage)message).setMimeType("text/plain");
            sendMessage(message, producer);
            // file blob message
            message = session.createBlobMessage(new File("pom.xml"));
            ((BlobMessage)message).setMimeType("text/plain");
            sendMessage(message, producer);
            // stream blob message
            message = session.createBlobMessage(new ByteArrayInputStream(TEST_MESSAGE.getBytes()));
            ((BlobMessage)message).setMimeType("text/plain");
            sendMessage(message, producer);

            // bytes message
            message = session.createBytesMessage();
            ((BytesMessage)message).writeBytes(TEST_MESSAGE.getBytes());
            sendMessage(message, producer);

            // map message
            message = session.createMapMessage();
            ((MapMessage)message).setString("message", TEST_MESSAGE);
            sendMessage(message, producer);

            // object message
            message = session.createObjectMessage(TEST_MESSAGE);
            ((ObjectMessage)message).setObject(TEST_MESSAGE);
            sendMessage(message, producer);

            // stream message
            message = session.createStreamMessage();
            ((StreamMessage)message).writeBytes(TEST_MESSAGE.getBytes());
            sendMessage(message, producer);

            System.out.println("Done.");

            ActiveMQConnection c = (ActiveMQConnection) connection;
            System.out.println("Results:\n");
            c.getConnectionStats().dump(new IndentPrinter());

        } catch (Exception e) {
            System.out.println("Caught: " + e);
            e.printStackTrace();
        } finally {
            try {
                connection.close();
            } catch (Throwable ignore) {
            }
        }
    }

    private void sendMessage(Message message, MessageProducer producer) throws JMSException {
        // set some generic properties and send
        message.setBooleanProperty("boolean", true);
        message.setByteProperty("byte", (byte) 1);
        message.setDoubleProperty("double", 1.0);
        message.setFloatProperty("float", 1.0f);
        message.setIntProperty("int", 1);
        message.setLongProperty("long", 1L);
        message.setShortProperty("short", (short) 1);
        message.setStringProperty("string", "value");
        message.setObjectProperty("object", "String object");

        // set a marker in the message for message type
        message.setJMSType(message.getClass().getSimpleName());

        producer.send(message);
    }

    public void setPassword(String pwd) {
        this.password = pwd;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public void setTopic(boolean topic) {
        this.topic = topic;
    }

    public void setQueue(boolean queue) {
        this.topic = !queue;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setUser(String user) {
        this.user = user;
    }

}
