/**
 * Main point of test execution
 */
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  struct TestingContext *test_ctx;
  char *emsg;
  struct GNUNET_PeerIdentity id;
  struct GNUNET_TESTING_SharedService ss[] = {
    {"peerinfo", cfg, 2},
    {NULL, NULL, 0}
  };
  struct GNUNET_TESTING_Peer *peer;
  unsigned int cnt;

  test_ctx = GNUNET_new (struct TestingContext);
  test_ctx->system =
      GNUNET_TESTING_system_create ("test-gnunet-testing",
                                    "127.0.0.1", NULL, ss);
  emsg = NULL;
  if (NULL == test_ctx->system)
    goto end;
  test_ctx->cfg = GNUNET_CONFIGURATION_dup (cfg);
  for (cnt = 0; cnt < NUM_PEERS; cnt++)
  {
    peer = GNUNET_TESTING_peer_configure (test_ctx->system,
                                          test_ctx->cfg,
                                          0, &id, &emsg);
    if (NULL == peer)
    {
      if (NULL != emsg)
        printf ("Test failed upon error: %s", emsg);
      goto end;
    }
    if (GNUNET_OK != GNUNET_TESTING_peer_start (peer))
    {
      GNUNET_TESTING_peer_destroy (peer);
      goto end;
    }
    test_ctx->peers[cnt] = peer;
  }
  status = GNUNET_OK;
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
                                &do_shutdown, test_ctx);
  return;

 end:
  GNUNET_SCHEDULER_add_now (&do_shutdown, test_ctx);
  GNUNET_free_non_null (emsg);
}
/**
 * Initialize the transport testing
 * @return transport testing handle
 */
struct GNUNET_TRANSPORT_TESTING_handle *
GNUNET_TRANSPORT_TESTING_init ()
{
  struct GNUNET_TRANSPORT_TESTING_handle *tth;

  /* prepare hostkeys */
  tth = GNUNET_new (struct GNUNET_TRANSPORT_TESTING_handle);

  /* Init testing the testing lib */
  tth->tl_system = GNUNET_TESTING_system_create ("transport-testing", NULL,
                                                 NULL, NULL);
  if (NULL == tth->tl_system)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Failed to initialize testing library!\n"));
    GNUNET_free (tth);
    return NULL;
  }

  return tth;
}
/**
 * Message handler for GNUNET_MESSAGE_TYPE_TESTBED_INIT messages
 *
 * @param cls NULL
 * @param client identification of the client
 * @param message the actual message
 */
static void
handle_init (void *cls, struct GNUNET_SERVER_Client *client,
             const struct GNUNET_MessageHeader *message)
{
  const struct GNUNET_TESTBED_InitMessage *msg;
  struct GNUNET_TESTBED_Host *host;
  const char *controller_hostname;
  char *ss_str;
  struct GNUNET_TESTING_SharedService *ss;
  unsigned int cnt;
  uint16_t msize;

  if (NULL != GST_context)
  {
    LOG_DEBUG ("We are being connected to laterally\n");
    GNUNET_SERVER_receive_done (client, GNUNET_OK);
    return;
  }
  msg = (const struct GNUNET_TESTBED_InitMessage *) message;
  msize = ntohs (message->size);
  if (msize <= sizeof (struct GNUNET_TESTBED_InitMessage))
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  msize -= sizeof (struct GNUNET_TESTBED_InitMessage);
  controller_hostname = (const char *) &msg[1];
  if ('\0' != controller_hostname[msize - 1])
  {
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  ss_str = NULL;
  ss = NULL;
  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (GST_config, "TESTBED",
                                                          "SHARED_SERVICES",
                                                          &ss_str))
  {
    ss = parse_shared_services (ss_str, GST_config);
    GNUNET_free (ss_str);
    ss_str = NULL;
  }
  GST_context = GNUNET_new (struct Context);
  GNUNET_SERVER_client_keep (client);
  GST_context->client = client;
  GST_context->host_id = ntohl (msg->host_id);
  GST_context->master_ip = GNUNET_strdup (controller_hostname);
  LOG_DEBUG ("Our IP: %s\n", GST_context->master_ip);
  GST_context->system =
      GNUNET_TESTING_system_create ("testbed", GST_context->master_ip,
                                    hostname, ss);
  if (NULL != ss)
  {
    for (cnt = 0; NULL != ss[cnt].service; cnt++)
    {
      ss_str = (char *) ss[cnt].service;
      GNUNET_free (ss_str);
    }
    GNUNET_free (ss);
    ss = NULL;
  }
  host =
      GNUNET_TESTBED_host_create_with_id (GST_context->host_id,
                                          GST_context->master_ip, NULL,
                                          GST_config, 0);
  host_list_add (host);
  LOG_DEBUG ("Created master context with host ID: %u\n", GST_context->host_id);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}