/**
 * Function scheduled to be run on the successful start of services
 * tries to look up the dns record for TEST_DOMAIN
 *
 * @param cls closure
 * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
 *                GNUNET_NO if content was already there or not found
 *                GNUNET_YES (or other positive value) on success
 * @param emsg NULL on success, otherwise an error message
 */
static void
commence_testing (void *cls,
		  int32_t success,
		  const char *emsg)
{
  nsqe = NULL;
  if (NULL != emsg)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to store record in namestore: %s\n",
		emsg);
    end_badly_now ();
    return;
  }
  gns_handle = GNUNET_GNS_connect (cfg);
  if (NULL == gns_handle)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to connect to GNS!\n");
    end_badly_now ();
    return;
  }
  lr = GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN, GNUNET_GNS_RECORD_A,
			  GNUNET_YES,
			  NULL,
			  &on_lookup_result, TEST_DOMAIN);
}
/**
 * Function scheduled to be run on the successful start of services
 * tries to look up the dns record for TEST_DOMAIN
 */
static void
commence_testing (void *cls, int32_t success, const char *emsg)
{
  char name[MAX_DNS_NAME_LENGTH];
  char* pos;
  struct GNUNET_CRYPTO_ShortHashAsciiEncoded hash_str;
  
  GNUNET_NAMESTORE_disconnect(namestore_handle, GNUNET_YES);

  gns_handle = GNUNET_GNS_connect(cfg);

  if (NULL == gns_handle)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to connect to GNS!\n");
  }

  pos = name;
  strcpy(pos, TEST_RECORD_NAME);
  pos += strlen(TEST_RECORD_NAME);
  strcpy(pos, ".");
  pos++;
  GNUNET_CRYPTO_short_hash_to_enc(&bob_hash, &hash_str);
  strcpy(pos, (char*)&hash_str);
  pos += strlen((char*)&hash_str);
  strcpy(pos, ".");
  pos++;
  strcpy(pos, GNUNET_GNS_TLD_ZKEY);

  GNUNET_GNS_lookup(gns_handle, name, GNUNET_GNS_RECORD_TYPE_A,
                    &on_lookup_result, NULL);
}
static void
on_lookup_result_zkey (void *cls, uint32_t rd_count,
		       const struct GNUNET_NAMESTORE_RecordData *rd)
{
  struct in_addr a;
  uint32_t i;
  char* addr;
  
  if (rd_count == 0)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Lookup failed, rp_filtering?\n");
    ok = 2;
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  ok = 1;
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
	      "name: %s\n", (char*)cls);
  for (i=0; i<rd_count; i++)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		"type: %d\n", rd[i].record_type);
    if (rd[i].record_type == GNUNET_GNS_RECORD_A)
    {
      memcpy (&a, rd[i].data, sizeof(a));
      addr = inet_ntoa(a);
      GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
		  "address: %s\n", addr);
      if (0 == strcmp (addr, TEST_IP_ZKEY))
      {
	GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		    "%s correctly resolved to %s!\n", 
		    TEST_DOMAIN_ZKEY, addr);
	ok = 0;
      }
    }
    else
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		  "No resolution!\n");
    }
  }  
  GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_DNS, GNUNET_GNS_RECORD_A,
		     GNUNET_YES,
		     NULL,
		     &on_lookup_result_dns, TEST_DOMAIN_DNS);
}
/**
 * Function scheduled to be run on the successful start of services
 * tries to look up the dns record for TEST_DOMAIN
 */
static void
commence_testing (void *cls, int32_t success, const char *emsg)
{
    GNUNET_NAMESTORE_disconnect(namestore_handle, GNUNET_YES);

    gns_handle = GNUNET_GNS_connect(cfg);

    if (NULL == gns_handle)
    {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                    "Failed to connect to GNS!\n");
    }

    GNUNET_GNS_lookup(gns_handle, TEST_DOMAIN, GNUNET_GNS_RECORD_MX,
                      &on_lookup_result, TEST_DOMAIN);
}
/**
 * Function scheduled to be run on the successful start of services
 * tries to look up the dns record for TEST_DOMAIN
 */
static void
commence_testing (void *cls, int32_t success, const char *emsg)
{
  gns_handle = GNUNET_GNS_connect(cfg);
  if (NULL == gns_handle)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to connect to GNS!\n");
    end_badly_now();
    return;
  }
  GNUNET_GNS_lookup(gns_handle, TEST_DOMAIN, GNUNET_GNS_RECORD_MX,
                    GNUNET_NO,
                    NULL,
                    &on_lookup_result, TEST_DOMAIN);
}
static void
on_lookup_result_dns (void *cls,
		      uint32_t rd_count,
		      const struct GNUNET_NAMESTORE_RecordData *rd)
{
  struct in_addr a;
  uint32_t i;
  char* addr;
  
  if (rd_count == 0)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "CNAME to DNS delegation failed. System offline?\n");
  }
  else
  {
    ok = 1;
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "name: %s\n", (char*)cls);
    for (i=0; i<rd_count; i++)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO, "type: %d\n", rd[i].record_type);
      if (rd[i].record_type == GNUNET_GNS_RECORD_A)
      {
	memcpy(&a, rd[i].data, sizeof(a));
	addr = inet_ntoa(a);
	GNUNET_log (GNUNET_ERROR_TYPE_INFO, "address: %s\n", addr);
	if (0 == strcmp(addr, TEST_IP_DNS))
	{
	  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		      "%s correctly resolved to %s!\n", TEST_DOMAIN_DNS, addr);
	  ok = 0;
	}
      }
      else
      {
	GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No resolution!\n");
      }
    }
  }
  GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_PLUS, GNUNET_GNS_RECORD_CNAME,
                     GNUNET_YES,
                     NULL,
                     &on_lookup_result_cname, TEST_DOMAIN_PLUS);
}
static void
commence_testing(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  static int wait = 0;
  wait++;
  if ((ZONE_PUT_WAIT_TIME.rel_value / 1000) == wait)
  {
    fprintf (stderr, "\n");
    wait_task = GNUNET_SCHEDULER_NO_TASK;
    lookup_handle = GNUNET_GNS_lookup(gh, TEST_DOMAIN, GNUNET_GNS_RECORD_A,
                      GNUNET_NO,
                      NULL,
                      &on_lookup_result, TEST_DOMAIN);
    if (GNUNET_SCHEDULER_NO_TASK != die_task)
      GNUNET_SCHEDULER_cancel(die_task);
    die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, "from lookup");
  }
  else
  {
      fprintf (stderr, ".");
      wait_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &commence_testing, NULL);
  }
}
/**
 * Function scheduled to be run on the successful start of services
 * tries to look up the dns record for TEST_DOMAIN
 *
 * @param cls closure
 * @param success GNUNET_SYSERR on failure (including timeout/queue drop/failure to validate)
 *                GNUNET_NO if content was already there or not found
 *                GNUNET_YES (or other positive value) on success
 * @param emsg NULL on success, otherwise an error message
 */
static void
commence_testing (void *cls, int32_t success, const char *emsg)
{
  if (NULL != emsg)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to store record in namestore: %s\n",
		emsg);
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  gns_handle = GNUNET_GNS_connect(cfg);
  if (NULL == gns_handle)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Failed to connect to GNS!\n");
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  GNUNET_GNS_lookup (gns_handle, TEST_DOMAIN_PLUS, GNUNET_GNS_RECORD_A,
		     GNUNET_YES,
		     NULL,
		     &on_lookup_result_plus, TEST_DOMAIN_PLUS);
}