/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/* Originally developed and coded by Makoto Matsumoto and Takuji
 * Nishimura.  Please mail <matumoto@math.keio.ac.jp>, if you're using
 * code from this file in your own programs or libraries.
 * Further information on the Mersenne Twister can be found at
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
 * This code was adapted to glib by Sebastian Wilhelmi.
 */

/*
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/.
 */

/*
 * MT safe
 */

#include "config.h"
#define _CRT_RAND_S

#include <math.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "grand.h"

#include "genviron.h"
#include "gmain.h"
#include "gmem.h"
#include "gtestutils.h"
#include "gthread.h"

#ifdef G_OS_WIN32
#include <stdlib.h>
#endif

/**
 * SECTION:random_numbers
 * @title: Random Numbers
 * @short_description: pseudo-random number generator
 *
 * The following functions allow you to use a portable, fast and good
 * pseudo-random number generator (PRNG).
 * 
 * <warning><para>Do not use this API for cryptographic purposes such as key
 * generation, nonces, salts or one-time pads.</para></warning>
 *
 * This PRNG is suitable for non-cryptographic use such as in games
 * (shuffling a card deck, generating levels), generating data for a
 * test suite, etc. If you need random data for cryptographic
 * purposes, it is recommended to use platform-specific APIs such as
 * <literal>/dev/random</literal> on Unix, or CryptGenRandom() on
 * Windows.
 *
 * GRand uses the Mersenne Twister PRNG, which was originally
 * developed by Makoto Matsumoto and Takuji Nishimura. Further
 * information can be found at <ulink
 * url="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html</ulink>.
 *
 * If you just need a random number, you simply call the
 * <function>g_random_*</function> functions, which will create a
 * globally used #GRand and use the according
 * <function>g_rand_*</function> functions internally. Whenever you
 * need a stream of reproducible random numbers, you better create a
 * #GRand yourself and use the <function>g_rand_*</function> functions
 * directly, which will also be slightly faster. Initializing a #GRand
 * with a certain seed will produce exactly the same series of random
 * numbers on all platforms. This can thus be used as a seed for e.g.
 * games.
 *
 * The <function>g_rand*_range</function> functions will return high
 * quality equally distributed random numbers, whereas for example the
 * <literal>(g_random_int()&percnt;max)</literal> approach often
 * doesn't yield equally distributed numbers.
 *
 * GLib changed the seeding algorithm for the pseudo-random number
 * generator Mersenne Twister, as used by
 * <structname>GRand</structname> and <structname>GRandom</structname>.
 * This was necessary, because some seeds would yield very bad
 * pseudo-random streams.  Also the pseudo-random integers generated by
 * <function>g_rand*_int_range()</function> will have a slightly better
 * equal distribution with the new version of GLib.
 *
 * The original seeding and generation algorithms, as found in GLib
 * 2.0.x, can be used instead of the new ones by setting the
 * environment variable <envar>G_RANDOM_VERSION</envar> to the value of
 * '2.0'. Use the GLib-2.0 algorithms only if you have sequences of
 * numbers generated with Glib-2.0 that you need to reproduce exactly.
 **/

/**
 * GRand:
 *
 * The #GRand struct is an opaque data structure. It should only be
 * accessed through the <function>g_rand_*</function> functions.
 **/

G_LOCK_DEFINE_STATIC (global_random);
static GRand* global_random = NULL;

/* Period parameters */  
#define N 624
#define M 397
#define MATRIX_A 0x9908b0df   /* constant vector a */
#define UPPER_MASK 0x80000000 /* most significant w-r bits */
#define LOWER_MASK 0x7fffffff /* least significant r bits */

/* Tempering parameters */   
#define TEMPERING_MASK_B 0x9d2c5680
#define TEMPERING_MASK_C 0xefc60000
#define TEMPERING_SHIFT_U(y)  (y >> 11)
#define TEMPERING_SHIFT_S(y)  (y << 7)
#define TEMPERING_SHIFT_T(y)  (y << 15)
#define TEMPERING_SHIFT_L(y)  (y >> 18)

static guint
get_random_version (void)
{
  static gsize initialized = FALSE;
  static guint random_version;

  if (g_once_init_enter (&initialized))
    {
      const gchar *version_string = g_getenv ("G_RANDOM_VERSION");
      if (!version_string || version_string[0] == '\000' || 
	  strcmp (version_string, "2.2") == 0)
	random_version = 22;
      else if (strcmp (version_string, "2.0") == 0)
	random_version = 20;
      else
	{
	  g_warning ("Unknown G_RANDOM_VERSION \"%s\". Using version 2.2.",
		     version_string);
	  random_version = 22;
	}
      g_once_init_leave (&initialized, TRUE);
    }
  
  return random_version;
}

struct _GRand
{
  guint32 mt[N]; /* the array for the state vector  */
  guint mti; 
};

/**
 * g_rand_new_with_seed:
 * @seed: a value to initialize the random number generator.
 * 
 * Creates a new random number generator initialized with @seed.
 * 
 * Return value: the new #GRand.
 **/
GRand*
g_rand_new_with_seed (guint32 seed)
{
  GRand *rand = g_new0 (GRand, 1);
  g_rand_set_seed (rand, seed);
  return rand;
}

/**
 * g_rand_new_with_seed_array:
 * @seed: an array of seeds to initialize the random number generator.
 * @seed_length: an array of seeds to initialize the random number generator.
 * 
 * Creates a new random number generator initialized with @seed.
 * 
 * Return value: the new #GRand.
 *
 * Since: 2.4
 **/
GRand*
g_rand_new_with_seed_array (const guint32 *seed, guint seed_length)
{
  GRand *rand = g_new0 (GRand, 1);
  g_rand_set_seed_array (rand, seed, seed_length);
  return rand;
}

/**
 * g_rand_new:
 * 
 * Creates a new random number generator initialized with a seed taken
 * either from <filename>/dev/urandom</filename> (if existing) or from 
 * the current time (as a fallback).  On Windows, the seed is taken from
 * rand_s().
 * 
 * Return value: the new #GRand.
 **/
GRand* 
g_rand_new (void)
{
  guint32 seed[4];
#ifdef G_OS_UNIX
  static gboolean dev_urandom_exists = TRUE;
  GTimeVal now;

  if (dev_urandom_exists)
    {
      FILE* dev_urandom;

      do
	{
	  dev_urandom = fopen("/dev/urandom", "rb");
	}
      while G_UNLIKELY (dev_urandom == NULL && errno == EINTR);

      if (dev_urandom)
	{
	  int r;

	  setvbuf (dev_urandom, NULL, _IONBF, 0);
	  do
	    {
	      errno = 0;
	      r = fread (seed, sizeof (seed), 1, dev_urandom);
	    }
	  while G_UNLIKELY (errno == EINTR);

	  if (r != 1)
	    dev_urandom_exists = FALSE;

	  fclose (dev_urandom);
	}	
      else
	dev_urandom_exists = FALSE;
    }

  if (!dev_urandom_exists)
    {  
      g_get_current_time (&now);
      seed[0] = now.tv_sec;
      seed[1] = now.tv_usec;
      seed[2] = getpid ();
      seed[3] = getppid ();
    }
#else /* G_OS_WIN32 */
  gint i;

  for (i = 0; i < G_N_ELEMENTS (seed); i++)
    rand_s (&seed[i]);
#endif

  return g_rand_new_with_seed_array (seed, 4);
}

/**
 * g_rand_free:
 * @rand_: a #GRand.
 *
 * Frees the memory allocated for the #GRand.
 **/
void
g_rand_free (GRand* rand)
{
  g_return_if_fail (rand != NULL);

  g_free (rand);
}

/**
 * g_rand_copy:
 * @rand_: a #GRand.
 *
 * Copies a #GRand into a new one with the same exact state as before.
 * This way you can take a snapshot of the random number generator for
 * replaying later.
 *
 * Return value: the new #GRand.
 *
 * Since: 2.4
 **/
GRand *
g_rand_copy (GRand* rand)
{
  GRand* new_rand;

  g_return_val_if_fail (rand != NULL, NULL);

  new_rand = g_new0 (GRand, 1);
  memcpy (new_rand, rand, sizeof (GRand));

  return new_rand;
}

/**
 * g_rand_set_seed:
 * @rand_: a #GRand.
 * @seed: a value to reinitialize the random number generator.
 *
 * Sets the seed for the random number generator #GRand to @seed.
 **/
void
g_rand_set_seed (GRand* rand, guint32 seed)
{
  g_return_if_fail (rand != NULL);

  switch (get_random_version ())
    {
    case 20:
      /* setting initial seeds to mt[N] using         */
      /* the generator Line 25 of Table 1 in          */
      /* [KNUTH 1981, The Art of Computer Programming */
      /*    Vol. 2 (2nd Ed.), pp102]                  */
      
      if (seed == 0) /* This would make the PRNG produce only zeros */
	seed = 0x6b842128; /* Just set it to another number */
      
      rand->mt[0]= seed;
      for (rand->mti=1; rand->mti<N; rand->mti++)
	rand->mt[rand->mti] = (69069 * rand->mt[rand->mti-1]);
      
      break;
    case 22:
      /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
      /* In the previous version (see above), MSBs of the    */
      /* seed affect only MSBs of the array mt[].            */
      
      rand->mt[0]= seed;
      for (rand->mti=1; rand->mti<N; rand->mti++)
	rand->mt[rand->mti] = 1812433253UL * 
	  (rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti; 
      break;
    default:
      g_assert_not_reached ();
    }
}

/**
 * g_rand_set_seed_array:
 * @rand_: a #GRand.
 * @seed: array to initialize with
 * @seed_length: length of array
 *
 * Initializes the random number generator by an array of
 * longs.  Array can be of arbitrary size, though only the
 * first 624 values are taken.  This function is useful
 * if you have many low entropy seeds, or if you require more then
 * 32bits of actual entropy for your application.
 *
 * Since: 2.4
 **/
void
g_rand_set_seed_array (GRand* rand, const guint32 *seed, guint seed_length)
{
  int i, j, k;

  g_return_if_fail (rand != NULL);
  g_return_if_fail (seed_length >= 1);

  g_rand_set_seed (rand, 19650218UL);

  i=1; j=0;
  k = (N>seed_length ? N : seed_length);
  for (; k; k--)
    {
      rand->mt[i] = (rand->mt[i] ^
		     ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1664525UL))
	      + seed[j] + j; /* non linear */
      rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
      i++; j++;
      if (i>=N)
        {
	  rand->mt[0] = rand->mt[N-1];
	  i=1;
	}
      if (j>=seed_length)
	j=0;
    }
  for (k=N-1; k; k--)
    {
      rand->mt[i] = (rand->mt[i] ^
		     ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1566083941UL))
	      - i; /* non linear */
      rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
      i++;
      if (i>=N)
        {
	  rand->mt[0] = rand->mt[N-1];
	  i=1;
	}
    }

  rand->mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 
}

/**
 * g_rand_boolean:
 * @rand_: a #GRand.
 *
 * Returns a random #gboolean from @rand_. This corresponds to a
 * unbiased coin toss.
 *
 * Returns: a random #gboolean.
 **/
/**
 * g_rand_int:
 * @rand_: a #GRand.
 *
 * Returns the next random #guint32 from @rand_ equally distributed over
 * the range [0..2^32-1].
 *
 * Return value: A random number.
 **/
guint32
g_rand_int (GRand* rand)
{
  guint32 y;
  static const guint32 mag01[2]={0x0, MATRIX_A};
  /* mag01[x] = x * MATRIX_A  for x=0,1 */

  g_return_val_if_fail (rand != NULL, 0);

  if (rand->mti >= N) { /* generate N words at one time */
    int kk;
    
    for (kk=0;kk<N-M;kk++) {
      y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
      rand->mt[kk] = rand->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
    }
    for (;kk<N-1;kk++) {
      y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
      rand->mt[kk] = rand->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
    }
    y = (rand->mt[N-1]&UPPER_MASK)|(rand->mt[0]&LOWER_MASK);
    rand->mt[N-1] = rand->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
    
    rand->mti = 0;
  }
  
  y = rand->mt[rand->mti++];
  y ^= TEMPERING_SHIFT_U(y);
  y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
  y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
  y ^= TEMPERING_SHIFT_L(y);
  
  return y; 
}

/* transform [0..2^32] -> [0..1] */
#define G_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10

/**
 * g_rand_int_range:
 * @rand_: a #GRand.
 * @begin: lower closed bound of the interval.
 * @end: upper open bound of the interval.
 *
 * Returns the next random #gint32 from @rand_ equally distributed over
 * the range [@begin..@end-1].
 *
 * Return value: A random number.
 **/
gint32 
g_rand_int_range (GRand* rand, gint32 begin, gint32 end)
{
  guint32 dist = end - begin;
  guint32 random;

  g_return_val_if_fail (rand != NULL, begin);
  g_return_val_if_fail (end > begin, begin);

  switch (get_random_version ())
    {
    case 20:
      if (dist <= 0x10000L) /* 2^16 */
	{
	  /* This method, which only calls g_rand_int once is only good
	   * for (end - begin) <= 2^16, because we only have 32 bits set
	   * from the one call to g_rand_int (). */
	  
	  /* we are using (trans + trans * trans), because g_rand_int only
	   * covers [0..2^32-1] and thus g_rand_int * trans only covers
	   * [0..1-2^-32], but the biggest double < 1 is 1-2^-52. 
	   */
	  
	  gdouble double_rand = g_rand_int (rand) * 
	    (G_RAND_DOUBLE_TRANSFORM +
	     G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM);
	  
	  random = (gint32) (double_rand * dist);
	}
      else
	{
	  /* Now we use g_rand_double_range (), which will set 52 bits for
	     us, so that it is safe to round and still get a decent
	     distribution */
	  random = (gint32) g_rand_double_range (rand, 0, dist);
	}
      break;
    case 22:
      if (dist == 0)
	random = 0;
      else 
	{
	  /* maxvalue is set to the predecessor of the greatest
	   * multiple of dist less or equal 2^32. */
	  guint32 maxvalue;
	  if (dist <= 0x80000000u) /* 2^31 */
	    {
	      /* maxvalue = 2^32 - 1 - (2^32 % dist) */
	      guint32 leftover = (0x80000000u % dist) * 2;
	      if (leftover >= dist) leftover -= dist;
	      maxvalue = 0xffffffffu - leftover;
	    }
	  else
	    maxvalue = dist - 1;
	  
	  do
	    random = g_rand_int (rand);
	  while (random > maxvalue);
	  
	  random %= dist;
	}
      break;
    default:
      random = 0;		/* Quiet GCC */
      g_assert_not_reached ();
    }      
 
  return begin + random;
}

/**
 * g_rand_double:
 * @rand_: a #GRand.
 *
 * Returns the next random #gdouble from @rand_ equally distributed over
 * the range [0..1).
 *
 * Return value: A random number.
 **/
gdouble 
g_rand_double (GRand* rand)
{    
  /* We set all 52 bits after the point for this, not only the first
     32. Thats why we need two calls to g_rand_int */
  gdouble retval = g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM;
  retval = (retval + g_rand_int (rand)) * G_RAND_DOUBLE_TRANSFORM;

  /* The following might happen due to very bad rounding luck, but
   * actually this should be more than rare, we just try again then */
  if (retval >= 1.0) 
    return g_rand_double (rand);

  return retval;
}

/**
 * g_rand_double_range:
 * @rand_: a #GRand.
 * @begin: lower closed bound of the interval.
 * @end: upper open bound of the interval.
 *
 * Returns the next random #gdouble from @rand_ equally distributed over
 * the range [@begin..@end).
 *
 * Return value: A random number.
 **/
gdouble 
g_rand_double_range (GRand* rand, gdouble begin, gdouble end)
{
  gdouble r;

  r = g_rand_double (rand);

  return r * end - (r - 1) * begin;
}

/**
 * g_random_boolean:
 *
 * Returns a random #gboolean. This corresponds to a unbiased coin toss.
 *
 * Returns: a random #gboolean.
 **/
/**
 * g_random_int:
 *
 * Return a random #guint32 equally distributed over the range
 * [0..2^32-1].
 *
 * Return value: A random number.
 **/
guint32
g_random_int (void)
{
  guint32 result;
  G_LOCK (global_random);
  if (!global_random)
    global_random = g_rand_new ();
  
  result = g_rand_int (global_random);
  G_UNLOCK (global_random);
  return result;
}

/**
 * g_random_int_range:
 * @begin: lower closed bound of the interval.
 * @end: upper open bound of the interval.
 *
 * Returns a random #gint32 equally distributed over the range
 * [@begin..@end-1].
 *
 * Return value: A random number.
 **/
gint32 
g_random_int_range (gint32 begin, gint32 end)
{
  gint32 result;
  G_LOCK (global_random);
  if (!global_random)
    global_random = g_rand_new ();
  
  result = g_rand_int_range (global_random, begin, end);
  G_UNLOCK (global_random);
  return result;
}

/**
 * g_random_double:
 *
 * Returns a random #gdouble equally distributed over the range [0..1).
 *
 * Return value: A random number.
 **/
gdouble 
g_random_double (void)
{
  double result;
  G_LOCK (global_random);
  if (!global_random)
    global_random = g_rand_new ();
  
  result = g_rand_double (global_random);
  G_UNLOCK (global_random);
  return result;
}

/**
 * g_random_double_range:
 * @begin: lower closed bound of the interval.
 * @end: upper open bound of the interval.
 *
 * Returns a random #gdouble equally distributed over the range [@begin..@end).
 *
 * Return value: A random number.
 **/
gdouble 
g_random_double_range (gdouble begin, gdouble end)
{
  double result;
  G_LOCK (global_random);
  if (!global_random)
    global_random = g_rand_new ();
 
  result = g_rand_double_range (global_random, begin, end);
  G_UNLOCK (global_random);
  return result;
}

/**
 * g_random_set_seed:
 * @seed: a value to reinitialize the global random number generator.
 * 
 * Sets the seed for the global random number generator, which is used
 * by the <function>g_random_*</function> functions, to @seed.
 **/
void
g_random_set_seed (guint32 seed)
{
  G_LOCK (global_random);
  if (!global_random)
    global_random = g_rand_new_with_seed (seed);
  else
    g_rand_set_seed (global_random, seed);
  G_UNLOCK (global_random);
}
