#include <stdio.h>

#include "arg.h"
#include "common.h"
#include "crd_ut10xx.h"

int
main(int argc, const char **argv)
{
	const char *help = 
		"\n\trbg [-help] [-devnum=num] [-devname=name] [-octets=num]\n\n"
		"\t-help\n"
		"\t\tPrint this information.\n\n"
		"\t-devnum\n"
		"\t\tSpecifies number of device which should be initialised.\n"
		"\t\tNumbers of devices can be foun calling info program.\n"
		"\t\tDefault value of this number is equal 0 and correspond to\n"
		"\t\tthe first device attached to host.\n\n"
		"\t-devname\n"
		"\t\tDevice can be specified by 'name' (only if configured).\n"
		"\t\tIf user defines also -devnum, then this option is ignored.\n\n"
		"\t-octets\n"
		"\t\tSpecifies number of random bit octets which should be\n"
		"\t\tgenerated by device. Default value of generated octets\n"
		"\t\tis 20.\n\n";
	
	CRD_UT10XX_t *ut;
	
	unsigned char buf[120];
	
	int devnum = -1;
	const char *devname = 0;
	int octets = 20;
	int bin = 0;
	
	int total = 0;
	int ones = 0;
	int status;
	
	int i;
	int j;
	
	if ( prologue(argv, help) )
		return (-1);
	
	if ( arg_getall(argv, "isib", "-devnum", &devnum, "-devname", &devname, 
		"-octets", &octets, "-bin", &bin) < 0 )
		return (-2);
	
	if ((devname == 0) && (devnum < 0))
		devnum = 0;
	
	if (devnum >= 0)
	{
		if ( (ut = CRD_UT10XX_find_by_index(devnum)) == 0 )
		{
			epilogue(stderr, "there is no device of that number, use 'info'"
				" to check\n", 0, 0);
			return (-3);
		}
	}
	else
	{
		if ( (ut = CRD_UT10XX_find_by_name(devname)) == 0 )
		{
			epilogue(stderr, "there is no device of this name, use 'info'"
				" to check\n", 0, 0);
			return (-4);
		}
	}
	
	CRD_UT10XX_session_open(ut);
	
	while (octets > 0)
	{
		if ( (status = CRD_UT10XX_cmd_rbg_generate_bits(ut, buf, octets > 120 ? 
			120 : octets)) < 0 )
		{
			epilogue(stderr, 0, status, ut);
			return (status);
		}
		
		for (i = 0; i < (octets > 120 ? 120 : octets); i++)
		{
			if (bin)
			{
				printf(":");
				
				for (j = 0; j < 8; j++, total++)
				{
					printf("%d", (buf[i] >> (7 - j)) & 0x01);
					
					if ((buf[i] >> (7 - j)) & 0x01)
						ones += 1;
				}
				
				if (i % 8 == 7) 
					printf("\n");
			}
			else
			{
				printf(":%02x", buf[i]);
				if (i % 30 == 29) 
					printf("\n");
			}
		}
		
		octets -= 120;
	}
	
	printf("\n");

	if (bin)
		printf("proportion: %0.4f\n\n", (double)ones / (double)total);
	
	CRD_UT10XX_session_close(ut);
	
	return (epilogue(stderr, 0, 0, 0));
}
