/**
   * Register, send 4 heartbeat, deregister.
   *
   * @throws IOException
   */
  @Test
  public void testHeartbeating() throws IOException {
    BlockingQueue<ServicePlatformMessage> muxQueue =
        new LinkedBlockingQueue<ServicePlatformMessage>();
    BlockingQueue<ServicePlatformMessage> dispatcherQueue =
        new LinkedBlockingQueue<ServicePlatformMessage>();

    TestProducer producer = new TestProducer(muxQueue, this);
    consumer = new TestConsumer(dispatcherQueue);
    AdaptorCore core = new AdaptorCore(muxQueue, dispatcherQueue, consumer, producer, 2);
    int counter = 0;

    core.start();
    Assert.assertNotNull(core.getUuid());

    try {
      while (counter < 4) {
        synchronized (mon) {
          mon.wait();
          if (lastHeartbeat.contains("RUNNING")) counter++;
        }
      }
    } catch (Exception e) {
      Assert.assertTrue(false);
    }

    System.out.println("Heartbeats received");
    Assert.assertTrue(true);

    core.stop();
    Assert.assertTrue(core.getState().equals("STOPPED"));
  }
  /**
   * Create a Mock wrapper
   *
   * @throws IOException
   */
  @Test
  public void testCreateMOCKWrapper() throws InterruptedException, IOException {
    String message =
        "{\"wr_type\":\"compute\",\"tenant_ext_net\":\"ext-subnet\",\"tenant_ext_router\":\"ext-router\",\"vim_type\":\"Mock\",\"vim_address\":\"http://localhost:9999\",\"username\":\"Eve\",\"pass\":\"Operator\",\"tenant\":\"operator\"}";
    String topic = "infrastructure.management.compute.add";
    BlockingQueue<ServicePlatformMessage> muxQueue =
        new LinkedBlockingQueue<ServicePlatformMessage>();
    BlockingQueue<ServicePlatformMessage> dispatcherQueue =
        new LinkedBlockingQueue<ServicePlatformMessage>();

    TestProducer producer = new TestProducer(muxQueue, this);
    ServicePlatformMessage addVimMessage =
        new ServicePlatformMessage(
            message, "application/json", topic, UUID.randomUUID().toString(), topic);
    consumer = new TestConsumer(dispatcherQueue);
    AdaptorCore core = new AdaptorCore(muxQueue, dispatcherQueue, consumer, producer, 0.05);

    core.start();

    consumer.injectMessage(addVimMessage);
    Thread.sleep(2000);
    while (output == null) {
      synchronized (mon) {
        mon.wait(1000);
      }
    }

    JSONTokener tokener = new JSONTokener(output);
    JSONObject jsonObject = (JSONObject) tokener.nextValue();
    String uuid = jsonObject.getString("uuid");
    String status = jsonObject.getString("status");
    Assert.assertTrue(status.equals("COMPLETED"));

    output = null;
    message = "{\"wr_type\":\"compute\",\"uuid\":\"" + uuid + "\"}";
    topic = "infrastructure.management.compute.remove";
    ServicePlatformMessage removeVimMessage =
        new ServicePlatformMessage(
            message, "application/json", topic, UUID.randomUUID().toString(), topic);
    consumer.injectMessage(removeVimMessage);

    while (output == null) {
      synchronized (mon) {
        mon.wait(1000);
      }
    }

    tokener = new JSONTokener(output);
    jsonObject = (JSONObject) tokener.nextValue();
    status = jsonObject.getString("status");
    Assert.assertTrue(status.equals("COMPLETED"));

    core.stop();
  }
  /**
   * Test list vim API call
   *
   * @throws IOException
   */
  @Test
  public void testListVimList() throws InterruptedException, IOException {

    ArrayList<String> vimUuid = new ArrayList<String>();
    JSONTokener tokener;
    JSONObject jsonObject;
    String uuid, status;

    BlockingQueue<ServicePlatformMessage> muxQueue =
        new LinkedBlockingQueue<ServicePlatformMessage>();
    BlockingQueue<ServicePlatformMessage> dispatcherQueue =
        new LinkedBlockingQueue<ServicePlatformMessage>();

    TestProducer producer = new TestProducer(muxQueue, this);
    consumer = new TestConsumer(dispatcherQueue);
    AdaptorCore core = new AdaptorCore(muxQueue, dispatcherQueue, consumer, producer, 0.05);

    core.start();
    String topic = "infrastructure.management.compute.add";

    for (int i = 0; i < 3; i++) {
      String message =
          "{\"wr_type\":\"compute\",\"tenant_ext_net\":\"ext-subnet\",\"tenant_ext_router\":\"ext-router\",\"vim_type\":\"Mock\",\"vim_address\":\"http://vim"
              + i
              + ":9999\",\"username\":\"Eve\",\"pass\":\"Operator\",\"tenant\":\"operator\"}";
      ServicePlatformMessage addVimMessage =
          new ServicePlatformMessage(
              message, "application/json", topic, UUID.randomUUID().toString(), topic);

      consumer.injectMessage(addVimMessage);
      Thread.sleep(2000);
      while (output == null) {
        synchronized (mon) {
          mon.wait(1000);
        }
      }

      tokener = new JSONTokener(output);
      jsonObject = (JSONObject) tokener.nextValue();
      uuid = jsonObject.getString("uuid");
      status = jsonObject.getString("status");
      Assert.assertTrue(status.equals("COMPLETED"));
      vimUuid.add(uuid);
      output = null;
    }

    topic = "infrastructure.management.compute.list";
    ServicePlatformMessage listVimMessage =
        new ServicePlatformMessage(null, null, topic, UUID.randomUUID().toString(), topic);
    consumer.injectMessage(listVimMessage);

    while (output == null) {
      synchronized (mon) {
        mon.wait(1000);
      }
    }
    ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
    VimResources[] vimList = mapper.readValue(output, VimResources[].class);
    ArrayList<String> vimArrayList = new ArrayList<String>();

    for (VimResources resource : vimList) {
      Assert.assertNotNull("Resource not set 'VIM UUID'", resource.getVimUuid());
      Assert.assertNotNull("Resource not set 'tot_cores'", resource.getCoreTotal());
      Assert.assertNotNull("Resource not set 'used_cores'", resource.getCoreUsed());
      Assert.assertNotNull("Resource not set 'tot_mem'", resource.getMemoryTotal());
      Assert.assertNotNull("Resource not set 'used_mem'", resource.getMemoryUsed());
      vimArrayList.add(resource.getVimUuid());
    }

    for (String returnUiid : vimUuid) {
      Assert.assertTrue(
          "VIMs List doesn't contain vim " + returnUiid, vimArrayList.contains(returnUiid));
    }

    output = null;

    for (String regUuid : vimUuid) {
      output = null;
      String removeMessage = "{\"wr_type\":\"compute\",\"uuid\":\"" + regUuid + "\"}";
      topic = "infrastructure.management.compute.remove";
      ServicePlatformMessage removeVimMessage =
          new ServicePlatformMessage(
              removeMessage, "application/json", topic, UUID.randomUUID().toString(), topic);
      consumer.injectMessage(removeVimMessage);

      while (output == null) {
        synchronized (mon) {
          mon.wait(1000);
        }
      }

      tokener = new JSONTokener(output);
      jsonObject = (JSONObject) tokener.nextValue();
      status = jsonObject.getString("status");
      Assert.assertTrue(status.equals("COMPLETED"));
    }

    output = null;
    consumer.injectMessage(listVimMessage);
    while (output == null) {
      synchronized (mon) {
        mon.wait(1000);
      }
    }

    vimList = mapper.readValue(output, VimResources[].class);

    Assert.assertTrue("VIMs List not empty", vimList.length == 0);

    output = null;

    core.stop();
    WrapperBay.getInstance().clear();
  }