/*
 * 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.hadoop.chukwa.datacollection.adaptor.jms;

import java.nio.charset.Charset;

import org.apache.hadoop.chukwa.datacollection.adaptor.AbstractAdaptor;
import org.apache.hadoop.chukwa.datacollection.adaptor.AdaptorException;
import org.apache.hadoop.chukwa.datacollection.adaptor.AdaptorShutdownPolicy;
import org.apache.hadoop.chukwa.Chunk;
import org.apache.hadoop.chukwa.ChunkImpl;
import org.apache.log4j.Logger;
import org.apache.activemq.ActiveMQConnectionFactory;

import javax.jms.TopicConnection;
import javax.jms.TopicSession;
import javax.jms.Session;
import javax.jms.Topic;
import javax.jms.Connection;
import javax.jms.MessageListener;
import javax.jms.Message;
import javax.jms.JMSException;
import javax.jms.ConnectionFactory;
import javax.jms.QueueConnection;
import javax.jms.QueueSession;
import javax.jms.Queue;
import javax.jms.MessageConsumer;

/**
 * Adaptor that is able to listen to a JMS topic or queue for messages, receive
 * the message, and transform it to a Chukwa chunk. Transformation is handled by
 * a JMSMessageTransformer. The default JMSMessageTransformer used is the
 * JMSTextMessageTransformer.
 * <P>
 * This adaptor is added to an Agent like so:
 * <code>
 * add JMSAdaptor &lt;dataType&gt; &lt;brokerURL&gt; &lt;-t &lt;topicName&gt; |-q &lt;queueName&gt; [-s &lt;JMSSelector&gt;]
 *  [-x &lt;transformerName&gt;] [-p &lt;transformerConfigs&gt;] &lt;offset&gt;
 * </code>
 * <ul>
 * <li><code>dataType</code> - The chukwa data type.</li>
 * <li><code>brokerURL</code> - The JMS broker URL to bind to.</li>
 * <li><code>topicName</code> - The JMS topic to listen on.</li>
 * <li><code>queueName</code> - The JMS queue to listen on.</li>
 * <li><code>JMSSelector</code> - The JMS selector to filter with. Surround
 * with quotes if selector contains multiple words.</li>
 * <li><code>transformerName</code> - Class name of the JMSMessageTransformer to
 * use.</li>
 * <li><code>transformerConfigs</code> - Properties to be passed to the
 * JMSMessageTransformer to use.  Surround with quotes if configs contain
 * multiple words.</li>
 * </ul>
 *
 * @see JMSMessageTransformer
 * @see JMSTextMessageTransformer
 */
public class JMSAdaptor extends AbstractAdaptor {

  static Logger log = Logger.getLogger(JMSAdaptor.class);

  ConnectionFactory connectionFactory = null;
  Connection connection;
  String brokerURL;
  String topic;
  String queue;
  String selector = null;
  JMSMessageTransformer transformer;

  volatile long bytesReceived = 0;
  String status; // used to write checkpoint info. See getStatus() below
  String source; // added to the chunk to identify the stream

  class JMSListener implements MessageListener {

    public void onMessage(Message message) {
      if (log.isDebugEnabled()) {
        log.debug("got a JMS message");
      }
      
      try {

        byte[] bytes = transformer.transform(message);
        if (bytes == null) {
          return;
        }

        bytesReceived += bytes.length;

        if (log.isDebugEnabled()) {
          log.debug("Adding Chunk from JMS message: " + new String(bytes, Charset.forName("UTF-8")));
        }

        Chunk c = new ChunkImpl(type, source, bytesReceived, bytes, JMSAdaptor.this);
        dest.add(c);

      } catch (JMSException e) {
        log.error("can't read JMS messages in " + adaptorID, e);
      }
      catch (InterruptedException e) {
        log.error("can't add JMS messages in " + adaptorID, e);
      }
    }
  }

  /**
   * This adaptor received configuration like this:
   * &lt;brokerURL&gt; &lt;-t &lt;topicName&gt;|-q &lt;queueName&gt;&gt; [-s &lt;JMSSelector&gt;] [-x &lt;transformerName&gt;]
   * [-p &lt;transformerProperties&gt;]
   *
   * @param s is a list of parameters
   * @return Adaptor ID
   */
  @Override
  public String parseArgs(String s) {
    if (log.isDebugEnabled()) {
      log.debug("Parsing args to initialize adaptor: " + s);
    }

    String[] tokens = s.split(" ");
    if (tokens.length < 1) {
      throw new IllegalArgumentException("Configuration must include brokerURL.");
    }

    brokerURL = tokens[0];

    if (brokerURL.length() < 6 || brokerURL.indexOf("://") == -1) {
      throw new IllegalArgumentException("Invalid brokerURL: " + brokerURL);
    }

    String transformerName = null;
    String transformerConfs = null;
    StringBuilder transformerConfsBuffer = new StringBuilder();
    for (int i = 1; i < tokens.length; i++) {
      String value = tokens[i];
      if ("-t".equals(value)) {
        topic = tokens[++i];
      }
      else if ("-q".equals(value)) {
        queue = tokens[++i];
      }
      else if ("-s".equals(value) && i <= tokens.length - 1) {
        selector = tokens[++i];

        // selector can have multiple words
        if (selector.startsWith("\"")) {
          for(int j = i + 1; j < tokens.length; j++) {
            selector = selector + " " + tokens[++i];
            if(tokens[j].endsWith("\"")) {
              break;
            }
          }
          selector = trimQuotes(selector);
        }
      }
      else if ("-x".equals(value)) {
        transformerName = tokens[++i];
      }
      else if ("-p".equals(value)) {
        transformerConfsBuffer.append(tokens[++i]);
        transformerConfs = transformerConfsBuffer.toString();

        // transformerConfs can have multiple words
        if (transformerConfsBuffer.toString().startsWith("\"")) {
          for(int j = i + 1; j < tokens.length; j++) {
            transformerConfsBuffer.append(" ");
            transformerConfsBuffer.append(tokens[++i]);
            if(tokens[j].endsWith("\"")) {
              break;
            }
          }
          transformerConfs = trimQuotes(transformerConfsBuffer.toString());
        }
      }
    }

    if (topic == null && queue == null) {
      log.error("topicName or queueName must be set");
      return null;
    }

    if (topic != null && queue != null) {
      log.error("Either topicName or queueName must be set, but not both");
      return null;
    }

    // create transformer
    if (transformerName != null) {
      try {
        Class<?> classDefinition = Class.forName(transformerName);
        Object object = classDefinition.newInstance();
        transformer = (JMSMessageTransformer)object;
      } catch (Exception e) {
        log.error("Couldn't find class for transformerName=" + transformerName, e);
        return null;
      }
    }
    else {
      transformer = new JMSTextMessageTransformer();
    }

    // configure transformer
    if (transformerConfs != null) {
      String result = transformer.parseArgs(transformerConfs);
      if (result == null) {
        log.error("JMSMessageTransformer couldn't parse transformer configs: " +
                transformerConfs);
        return null;
      }
    }

    status = s;

    if(topic != null) {
      source = "jms:"+brokerURL + ",topic:" + topic;
    }
    else if(queue != null) {
      source = "jms:"+brokerURL + ",queue:" + queue;
    }

    return s;
  }

  @Override
  public void start(long offset) throws AdaptorException {

    try {
      bytesReceived = offset;

      connectionFactory = initializeConnectionFactory(brokerURL);
      connection = connectionFactory.createConnection();

      log.info("Starting JMS adaptor: " + adaptorID + " started on brokerURL=" + brokerURL +
              ", topic=" + topic + ", selector=" + selector +
              ", offset =" + bytesReceived);

      // this is where different initialization could be used for a queue
      if(topic != null) {
        initializeTopic(connection, topic, selector, new JMSListener());
      }
      else if(queue != null) {
        initializeQueue(connection, queue, selector, new JMSListener());
      }
      connection.start();

    } catch(Exception e) {
      throw new AdaptorException(e);
    }
  }

  /**
   * Override this to initialize with a different connection factory.
   * @param brokerURL
   * @return
   */
  protected ConnectionFactory initializeConnectionFactory(String brokerURL) {
    return new ActiveMQConnectionFactory(brokerURL);
  }

  /**
   * Status is used to write checkpoints. Checkpoints are written as:
   * ADD &lt;adaptorKey&gt; = &lt;adaptorClass&gt; &lt;currentStatus&gt; &lt;offset&gt;
   *
   * Once they're reloaded, adaptors are re-initialized with
   * &lt;adaptorClass&gt; &lt;currentStatus&gt; &lt;offset&gt;
   *
   * While doing so, this gets passed by to the parseArgs method:
   * &lt;currentStatus&gt;
   *
   * Without the first token in &lt;currentStatus&gt;, which is expected to be &lt;dataType&gt;.
   *
   * @return Adaptor status
   */
  @Override
  public String getCurrentStatus() {
    return type + " " + status;
  }

  @Override
  public long shutdown(AdaptorShutdownPolicy shutdownPolicy)
      throws AdaptorException {
    try {
      connection.close();

    } catch(Exception e) {
      log.error("Exception closing JMS connection.", e);
    }

    return bytesReceived;
  }

  private void initializeTopic(Connection connection,
                                      String topic,
                                      String selector,
                                      JMSListener listener) throws JMSException {
    TopicSession session = ((TopicConnection)connection).
            createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    Topic jmsTopic = session.createTopic(topic);
    MessageConsumer consumer = session.createConsumer(jmsTopic, selector, true);
    consumer.setMessageListener(listener);
  }

  private void initializeQueue(Connection connection,
                                      String topic,
                                      String selector,
                                      JMSListener listener) throws JMSException {
    QueueSession session = ((QueueConnection)connection).
            createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    Queue queue = session.createQueue(topic);
    MessageConsumer consumer = session.createConsumer(queue, selector, true);
    consumer.setMessageListener(listener);
  }

  private static String trimQuotes(String value) {
    // trim leading and trailing quotes
    if (value.charAt(0) == '"') {
      value = value.substring(1);
    }
    if (value.charAt(value.length() - 1) == '"') {
      value = value.substring(0, value.length() - 1);
    }
    return value;
  }

}