/**
 * 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.
 */
package org.apache.camel.component.jms;

import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.apache.camel.Exchange;
import org.apache.camel.util.ExchangeHelper;
import org.apache.camel.util.ObjectHelper;

import static org.apache.camel.component.jms.JmsConfiguration.QUEUE_PREFIX;
import static org.apache.camel.component.jms.JmsConfiguration.TEMP_QUEUE_PREFIX;
import static org.apache.camel.component.jms.JmsConfiguration.TEMP_TOPIC_PREFIX;
import static org.apache.camel.component.jms.JmsConfiguration.TOPIC_PREFIX;
import static org.apache.camel.util.StringHelper.removeStartingCharacters;

/**
 * Utility class for {@link javax.jms.Message}.
 *
 * @version
 */
public final class JmsMessageHelper {

    private JmsMessageHelper() {
    }

    /**
     * Removes the property from the JMS message.
     *
     * @param jmsMessage the JMS message
     * @param name       name of the property to remove
     * @return the old value of the property or <tt>null</tt> if not exists
     * @throws JMSException can be thrown
     */
    public static Object removeJmsProperty(Message jmsMessage, String name) throws JMSException {
        // check if the property exists
        if (!jmsMessage.propertyExists(name)) {
            return null;
        }

        Object answer = null;

        // store the properties we want to keep in a temporary map
        // as the JMS API is a bit strict as we are not allowed to
        // clear a single property, but must clear them all and redo
        // the properties
        Map<String, Object> map = new LinkedHashMap<>();
        Enumeration<?> en = jmsMessage.getPropertyNames();
        while (en.hasMoreElements()) {
            String key = (String) en.nextElement();
            if (name.equals(key)) {
                answer = key;
            } else {
                map.put(key, getProperty(jmsMessage, key));
            }
        }

        // redo the properties to keep
        jmsMessage.clearProperties();
        for (Entry<String, Object> entry : map.entrySet()) {
            jmsMessage.setObjectProperty(entry.getKey(), entry.getValue());
        }

        return answer;
    }

    /**
     * Tests whether a given property with the name exists
     *
     * @param jmsMessage the JMS message
     * @param name       name of the property to test if exists
     * @return <tt>true</tt> if the property exists, <tt>false</tt> if not.
     * @throws JMSException can be thrown
     */
    public static boolean hasProperty(Message jmsMessage, String name) throws JMSException {
        Enumeration<?> en = jmsMessage.getPropertyNames();
        while (en.hasMoreElements()) {
            String key = (String) en.nextElement();
            if (name.equals(key)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Gets a JMS property
     *
     * @param jmsMessage the JMS message
     * @param name       name of the property to get
     * @return the property value, or <tt>null</tt> if does not exists
     * @throws JMSException can be thrown
     */
    public static Object getProperty(Message jmsMessage, String name) throws JMSException {
        Object value = jmsMessage.getObjectProperty(name);
        if (value == null) {
            value = jmsMessage.getStringProperty(name);
        }
        return value;
    }

    /**
     * Gets a JMS property in a safe way
     *
     * @param jmsMessage the JMS message
     * @param name       name of the property to get
     * @return the property value, or <tt>null</tt> if does not exists or failure to get the value
     */
    public static Long getSafeLongProperty(Message jmsMessage, String name) {
        try {
            return jmsMessage.getLongProperty(name);
        } catch (Exception e) {
            // ignore
        }
        return null;
    }

    /**
     * Is the JMS session from a given vendor
     *
     * @param session the JMS session
     * @param vendor the vendor, such as <tt>ActiveMQ</tt>, or <tt>Artemis</tt>
     * @return <tt>true</tt> if from the vendor, <tt>false</tt> if not or not possible to determine
     */
    public static boolean isVendor(Session session, String vendor) {
        if ("Artemis".equals(vendor)) {
            return session.getClass().getName().startsWith("org.apache.activemq.artemis");
        } else if ("ActiveMQ".equals(vendor)) {
            return !isVendor(session, "Artemis") && session.getClass().getName().startsWith("org.apache.activemq");
        }
        return false;
    }

    /**
     * Sets the property on the given JMS message.
     *
     * @param jmsMessage  the JMS message
     * @param name        name of the property to set
     * @param value       the value
     * @throws JMSException can be thrown
     */
    public static void setProperty(Message jmsMessage, String name, Object value) throws JMSException {
        if (value == null) {
            return;
        }
        if (value instanceof Byte) {
            jmsMessage.setByteProperty(name, (Byte) value);
        } else if (value instanceof Boolean) {
            jmsMessage.setBooleanProperty(name, (Boolean) value);
        } else if (value instanceof Double) {
            jmsMessage.setDoubleProperty(name, (Double) value);
        } else if (value instanceof Float) {
            jmsMessage.setFloatProperty(name, (Float) value);
        } else if (value instanceof Integer) {
            jmsMessage.setIntProperty(name, (Integer) value);
        } else if (value instanceof Long) {
            jmsMessage.setLongProperty(name, (Long) value);
        } else if (value instanceof Short) {
            jmsMessage.setShortProperty(name, (Short) value);
        } else if (value instanceof String) {
            jmsMessage.setStringProperty(name, (String) value);
        } else {
            // fallback to Object
            jmsMessage.setObjectProperty(name, value);
        }
    }

    /**
     * Sets the correlation id on the JMS message.
     * <p/>
     * Will ignore exception thrown
     *
     * @param message  the JMS message
     * @param correlationId the correlation id
     */
    public static void setCorrelationId(Message message, String correlationId) {
        try {
            message.setJMSCorrelationID(correlationId);
        } catch (JMSException e) {
            // ignore
        }
    }

    /**
     * Whether the destination name has either queue or temp queue prefix.
     *
     * @param destination the destination
     * @return <tt>true</tt> if queue or temp-queue prefix, <tt>false</tt> otherwise
     */
    public static boolean isQueuePrefix(String destination) {
        if (ObjectHelper.isEmpty(destination)) {
            return false;
        }

        return destination.startsWith(QUEUE_PREFIX) || destination.startsWith(TEMP_QUEUE_PREFIX);
    }

    /**
     * Whether the destination name has either topic or temp topic prefix.
     *
     * @param destination the destination
     * @return <tt>true</tt> if topic or temp-topic prefix, <tt>false</tt> otherwise
     */
    public static boolean isTopicPrefix(String destination) {
        if (ObjectHelper.isEmpty(destination)) {
            return false;
        }

        return destination.startsWith(TOPIC_PREFIX) || destination.startsWith(TEMP_TOPIC_PREFIX);
    }

    /**
     * Normalizes the destination name.
     * <p/>
     * This ensures the destination name is correct, and we do not create queues as <tt>queue://queue:foo</tt>, which
     * was intended as <tt>queue://foo</tt>.
     *
     * @param destination the destination
     * @return the normalized destination
     */
    public static String normalizeDestinationName(String destination) {
        // do not include prefix which is the current behavior when using this method.
        return normalizeDestinationName(destination, false);
    }

    /**
     * Normalizes the destination name.
     * <p/>
     * This ensures the destination name is correct, and we do not create queues as <tt>queue://queue:foo</tt>, which
     * was intended as <tt>queue://foo</tt>.
     *
     * @param destination the destination
     * @param includePrefix whether to include <tt>queue://</tt>, or <tt>topic://</tt> prefix in the normalized destination name
     * @return the normalized destination
     */
    public static String normalizeDestinationName(String destination, boolean includePrefix) {
        if (ObjectHelper.isEmpty(destination)) {
            return destination;
        }
        if (destination.startsWith(QUEUE_PREFIX)) {
            String s = removeStartingCharacters(destination.substring(QUEUE_PREFIX.length()), '/');
            if (includePrefix) {
                s = QUEUE_PREFIX + "//" + s;
            }
            return s;
        } else if (destination.startsWith(TEMP_QUEUE_PREFIX)) {
            String s = removeStartingCharacters(destination.substring(TEMP_QUEUE_PREFIX.length()), '/');
            if (includePrefix) {
                s = TEMP_QUEUE_PREFIX + "//" + s;
            }
            return s;
        } else if (destination.startsWith(TOPIC_PREFIX)) {
            String s = removeStartingCharacters(destination.substring(TOPIC_PREFIX.length()), '/');
            if (includePrefix) {
                s = TOPIC_PREFIX + "//" + s;
            }
            return s;
        } else if (destination.startsWith(TEMP_TOPIC_PREFIX)) {
            String s = removeStartingCharacters(destination.substring(TEMP_TOPIC_PREFIX.length()), '/');
            if (includePrefix) {
                s = TEMP_TOPIC_PREFIX + "//" + s;
            }
            return s;
        } else {
            return destination;
        }
    }

    /**
     * Sets the JMSReplyTo on the message.
     *
     * @param message  the message
     * @param replyTo  the reply to destination
     */
    public static void setJMSReplyTo(Message message, Destination replyTo) {
        try {
            message.setJMSReplyTo(replyTo);
        } catch (Exception e) {
            // ignore due OracleAQ does not support accessing JMSReplyTo
        }
    }

    /**
     * Gets the JMSReplyTo from the message.
     *
     * @param message  the message
     * @return the reply to, can be <tt>null</tt>
     */
    public static Destination getJMSReplyTo(Message message) {
        try {
            return message.getJMSReplyTo();
        } catch (Exception e) {
            // ignore due OracleAQ does not support accessing JMSReplyTo
        }

        return null;
    }

    /**
     * Gets the JMSType from the message.
     *
     * @param message  the message
     * @return the type, can be <tt>null</tt>
     */
    public static String getJMSType(Message message) {
        try {
            return message.getJMSType();
        } catch (Exception e) {
            // ignore due OracleAQ does not support accessing JMSType
        }

        return null;
    }

    /**
     * Gets the String Properties from the message.
     *
     * @param message  the message
     * @return the type, can be <tt>null</tt>
     */
    public static String getStringProperty(Message message, String propertyName) {
        try {
            return message.getStringProperty(propertyName);
        } catch (Exception e) {
            // ignore due some broker client does not support accessing StringProperty
        }

        return null;
    }

    /**
     * Gets the JMSRedelivered from the message.
     *
     * @param message  the message
     * @return <tt>true</tt> if redelivered, <tt>false</tt> if not, <tt>null</tt> if not able to determine
     */
    public static Boolean getJMSRedelivered(Message message) {
        try {
            return message.getJMSRedelivered();
        } catch (Exception e) {
            // ignore if JMS broker do not support this
        }

        return null;
    }

    /**
     * Gets the JMSMessageID from the message.
     *
     * @param message  the message
     * @return the JMSMessageID, or <tt>null</tt> if not able to get
     */
    public static String getJMSMessageID(Message message) {
        try {
            return message.getJMSMessageID();
        } catch (Exception e) {
            // ignore if JMS broker do not support this
        }

        return null;
    }

    /**
     * Gets the JMSDestination from the message.
     *
     * @param message  the message
     * @return the JMSDestination, or <tt>null</tt> if not able to get
     */
    public static Destination getJMSDestination(Message message) {
        try {
            return message.getJMSDestination();
        } catch (Exception e) {
            // ignore if JMS broker do not support this
        }

        return null;
    }

    /**
     * Sets the JMSDeliveryMode on the message.
     *
     * @param exchange the exchange
     * @param message  the message
     * @param deliveryMode  the delivery mode, either as a String or integer
     * @throws javax.jms.JMSException is thrown if error setting the delivery mode
     */
    public static void setJMSDeliveryMode(Exchange exchange, Message message, Object deliveryMode) throws JMSException {
        Integer mode = null;

        if (deliveryMode instanceof String) {
            String s = (String) deliveryMode;
            if ("PERSISTENT".equalsIgnoreCase(s)) {
                mode = DeliveryMode.PERSISTENT;
            } else if ("NON_PERSISTENT".equalsIgnoreCase(s)) {
                mode = DeliveryMode.NON_PERSISTENT;
            } else {
                // it may be a number in the String so try that
                Integer value = ExchangeHelper.convertToType(exchange, Integer.class, deliveryMode);
                if (value != null) {
                    mode = value;
                } else {
                    throw new IllegalArgumentException("Unknown delivery mode with value: " + deliveryMode);
                }
            }
        } else {
            // fallback and try to convert to a number
            Integer value = ExchangeHelper.convertToType(exchange, Integer.class, deliveryMode);
            if (value != null) {
                mode = value;
            }
        }

        if (mode != null) {
            message.setJMSDeliveryMode(mode);
            message.setIntProperty(JmsConstants.JMS_DELIVERY_MODE, mode);
        }
    }

    /**
     * Gets the JMSCorrelationIDAsBytes from the message.
     *
     * @param message the message
     * @return the JMSCorrelationIDAsBytes, or <tt>null</tt> if not able to get
     */
    public static String getJMSCorrelationIDAsBytes(Message message) {
        try {
            byte[] bytes = message.getJMSCorrelationIDAsBytes();
            boolean isNull = true;
            for (byte b : bytes) {
                if (b != 0) {
                    isNull = false;
                }
            }
            return isNull ? null : new String(bytes);
        } catch (Exception e) {
            // ignore if JMS broker do not support this
        }
        return null;
    }
}
