/*
 * Copyright (c) 2015 Fraunhofer FOKUS
 * Licensed 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.openbaton.plugin;

import com.rabbitmq.client.ConnectionFactory;
import org.openbaton.catalogue.nfvo.ManagerCredentials;
import org.openbaton.plugin.utils.Utils;
import org.openbaton.registration.Registration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeoutException;

/**
 * Created by lto on 09/09/15.
 */
public class PluginStarter {

  protected static final Logger log = LoggerFactory.getLogger(PluginStarter.class);
  private static Map<String, PluginListener> plugins = new HashMap<String, PluginListener>();
  private static Properties properties;
  private static ExecutorService executor;

  private static String getFinalName(Class clazz, String name) throws IOException {
    getProperties(clazz);
    String inte = Utils.checkInterface(clazz);
    if (inte.equals("unknown-interface")) // no interface found
    throw new RuntimeException(
          "The plugin class "
              + clazz.getSimpleName()
              + " needs to extend or VimDriver or Monitoring classes");
    return inte + "." + properties.getProperty("type", "unknown") + "." + name;
  }

  private static void getProperties(Class clazz) throws IOException {
    properties = new Properties();
    properties.load(clazz.getResourceAsStream("/plugin.conf.properties"));
  }

  public static void registerPlugin(
      Class clazz, String name, String brokerIp, int port, int consumers)
      throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException,
          InstantiationException, TimeoutException, InterruptedException {
    getProperties(clazz);
    String username = properties.getProperty("username", "admin");
    String password = properties.getProperty("password", "openbaton");
    String virtualHost = properties.getProperty("virtual-host", "/");
    registerPlugin(clazz, name, brokerIp, port, consumers, username, password, virtualHost);
  }

  protected static void registerPlugin(
      Class clazz,
      String name,
      String brokerIp,
      int port,
      int consumers,
      String username,
      String password,
      String virtualHost)
      throws IOException, InstantiationException, IllegalAccessException, InvocationTargetException,
          NoSuchMethodException, TimeoutException, InterruptedException {
    Registration registration = new Registration();
    ManagerCredentials managerCredentials =
        registration.registerPluginToNfvo(
            brokerIp, port, username, password, virtualHost, getFinalName(clazz, name));
    // registration.registerPluginToNfvo(factory, pluginId);
    if (properties == null) getProperties(clazz);
    executor = Executors.newFixedThreadPool(consumers);
    for (int i = 0; i < consumers; i++) {
      PluginListener pluginListener = new PluginListener();
      pluginListener.setPluginId(getFinalName(clazz, name));
      pluginListener.setPluginInstance(clazz.getConstructor().newInstance());
      pluginListener.setBrokerIp(brokerIp);
      pluginListener.setBrokerPort(port);
      pluginListener.setUsername(managerCredentials.getRabbitUsername());
      pluginListener.setPassword(managerCredentials.getRabbitPassword());
      pluginListener.setVirtualHost(virtualHost);

      executor.execute(pluginListener);
    }
  }
}

@@ -1117,16 +1117,54 @@
 cutors;%0A
+import java.util.concurrent.TimeUnit;%0A
 import j
@@ -2894,24 +2894,30 @@
 name,%0A      
+final 
 String broke
@@ -2923,24 +2923,30 @@
 erIp,%0A      
+final 
 int port,%0A  
@@ -2966,24 +2966,30 @@
 mers,%0A      
+final 
 String usern
@@ -2995,24 +2995,30 @@
 name,%0A      
+final 
 String passw
@@ -3024,24 +3024,30 @@
 word,%0A      
+final 
 String virtu
@@ -3233,16 +3233,71 @@
 n %7B%0A    
+String pluginId = getFinalName(clazz, name);%0A    final 
 Registra
@@ -3340,16 +3340,22 @@
 ();%0A    
+final 
 ManagerC
@@ -3494,33 +3494,732 @@
 st, 
-getFinalName(clazz, name)
+pluginId);%0A    Runtime.getRuntime()%0A        .addShutdownHook(%0A            new Thread() %7B%0A              @Override%0A              public void run() %7B%0A                try %7B%0A                  registration.deregisterPluginFromNfvo(%0A                      brokerIp,%0A                      port,%0A                      username,%0A                      password,%0A                      virtualHost,%0A                      managerCredentials.getRabbitUsername(),%0A                      managerCredentials.getRabbitPassword());%0A                %7D catch (IOException e) %7B%0A                  e.printStackTrace();%0A                %7D catch (TimeoutException e) %7B%0A                  e.printStackTrace();%0A                %7D%0A              %7D%0A            %7D
 );%0A 
@@ -4523,33 +4523,16 @@
 nId(
-getFinalName(clazz, name)
+pluginId
 );%0A 

Add deregister after plugin stops