#include "../test.h"

#include <aerospike/as_random.h>
#include <pthread.h>
#include <string.h>
#include <ctype.h>

/******************************************************************************
 * TEST CASES
 *****************************************************************************/

static uint64_t n3, n4, n5, n6;

static void*
worker1(void* data)
{
	n3 = as_random_get_uint64();
	n4 = as_random_get_uint64();
	return NULL;
}

static void*
worker2(void* data)
{
	n5 = as_random_get_uint64();
	n6 = as_random_get_uint64();
	return NULL;
}

TEST(random_number, "random numbers" )
{
	pthread_t thread1;
	pthread_create(&thread1, NULL, worker1, NULL);
	
	pthread_t thread2;
	pthread_create(&thread2, NULL, worker2, NULL);
	
	uint64_t n1 = as_random_get_uint64();
	uint64_t n2 = as_random_get_uint64();
	
	pthread_join(thread1, NULL);
	pthread_join(thread2, NULL);
	
	assert(n1 != n2 && n1 != n3 && n1 != n4 && n1 != n5 && n1 != n6);
	assert(n2 != n3 && n2 != n4 && n2 != n5 && n2 != n6);
	assert(n3 != n4 && n3 != n5 && n3 != n6);
	assert(n4 != n5 && n4 != n6);
	assert(n5 != n6);
}

TEST(random_bytes, "random bytes" )
{
	uint8_t b1[3];
	memset(b1, 0, sizeof(b1));
	
	as_random_get_bytes(b1, 0);
	assert(b1[0] == 0);
	
	as_random_get_bytes(b1, 2);
	assert(b1[2] == 0);
	
	uint8_t b2[64];
	memset(b2, 0, sizeof(b2));
	
	as_random_get_bytes(b2, 8);
	assert(b2[8] == 0);
	
	as_random_get_bytes(b2, 63);
	assert(b2[63] == 0);
}

TEST(random_str, "random string" )
{
	char buf[10];
	int len = sizeof(buf) - 1;
	as_random_get_str(buf, len);

	for (int i = 0; i < len; i++) {
		int rv = isalnum(buf[i]);
		assert(rv != 0);
	}
}

/******************************************************************************
 * TEST SUITE
 *****************************************************************************/

SUITE(random_numbers, "random number generator")
{
    suite_add(random_number);
    suite_add(random_bytes);
    suite_add(random_str);
}
