package com.googlesource.gerrit.plugins.rabbitmq;

import com.google.gerrit.extensions.annotations.PluginName;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import org.apache.commons.codec.CharEncoding;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.UUID;

@Singleton
public class AMQPSession {

  private static final Logger LOGGER = LoggerFactory.getLogger(AMQPSession.class);
  private static final String EXCHANGE_TYPE_DIRECT ="direct";
  private final Properties properties;
  private final String pluginName;
  private Connection connection;
  private Channel publishChannel;
  private String exchangeName;

  interface Factory {
    public AMQPSession create();
  }

  @Inject
  public AMQPSession(@PluginName String pluginName, Properties properties) {
    this.properties = properties;
    this.pluginName = pluginName;
  }

  public void connect() {
    ConnectionFactory factory = new ConnectionFactory();
    try {
      if (StringUtils.isNotEmpty(properties.getAMQPUri())) {
        factory.setUri(properties.getAMQPUri());
        if (StringUtils.isNotEmpty(properties.getAMQPUsername())) {
          factory.setUsername(properties.getAMQPUsername());
        }
        if (StringUtils.isNotEmpty(properties.getAMQPPassword())) {
          factory.setPassword(properties.getAMQPPassword());
        }
        connection = factory.newConnection();
        Channel ch = connection.createChannel();
        if (StringUtils.isNotEmpty(properties.getAMQPQueue())) {
          exchangeName = UUID.randomUUID().toString();
          ch.exchangeDeclare(exchangeName, EXCHANGE_TYPE_DIRECT, true);
          ch.queueDeclare(properties.getAMQPQueue(), true, false, false, null);
          ch.queueBind(properties.getAMQPQueue(), exchangeName, "com.sonymobile.plugin.demo");
          publishChannel = ch;
        } else {
          exchangeName = properties.getAMQPExchange();
          if (StringUtils.isNotEmpty(exchangeName)) {
            ch.exchangeDeclarePassive(exchangeName);
            publishChannel = ch;
          }
        }
      }
    } catch (Exception ex) {
      LOGGER.warn("#connect: " + ex.toString());
    }
  }

  public void disconnect() {
    if (connection != null) {
      try {
        publishChannel.close();
        connection.close();
      } catch (Exception ex) {
        LOGGER.warn("#disconnect: " + ex.toString());
        ex.printStackTrace();
      } finally {
        connection = null;
        publishChannel = null;
      }
    }
  }

  public void sendMessage(String message) {
    if (publishChannel != null && publishChannel.isOpen()) {
      try {
        publishChannel.basicPublish(exchangeName, properties.getAMQPRoutingKey(), null, message.getBytes(CharEncoding.UTF_8));
      } catch (Exception ex) {
        LOGGER.warn("#sendMessage: " + ex.toString());
      }
    }
  }
}

@@ -652,16 +652,78 @@
 irect%22;%0A
+  private static final String EXCHANGE_TYPE_FANOUT =%22fanout%22;%0A
   privat
@@ -1679,24 +1679,77 @@
 eChannel();%0A
+        exchangeName = UUID.randomUUID().toString();%0A
         if (
@@ -1807,32 +1807,39 @@
 %7B%0A          
+String 
 exchange
 Name = UUID.
@@ -1830,44 +1830,235 @@
 ange
-Nam
+Typ
 e = 
-UUID.randomUUID().toString();
+EXCHANGE_TYPE_DIRECT;;%0A          String routingKey = properties.getAMQPRoutingKey();%0A          if (routingKey.isEmpty()) %7B%0A            exchangeType = EXCHANGE_TYPE_FANOUT;%0A            routingKey = pluginName;%0A          %7D
 %0A   
@@ -2097,36 +2097,28 @@
 geName, 
-EXCHANGE_TYPE_DIRECT
+exchangeType
 , true);
@@ -2266,36 +2266,18 @@
 me, 
-%22com.sonymobile.plugin.demo%22
+routingKey
 );%0A 

Determine exchange type and routingkey from properties