/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * 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.1 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, see <http://www.gnu.org/licenses/>.
 */

/* 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>
#include "grand.h"

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

#ifdef G_OS_UNIX
#include <unistd.h>
#endif

#ifdef G_OS_WIN32
#include <stdlib.h>
#include <process.h> /* For getpid() */
#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).
 * 
 * Do not use this API for cryptographic purposes such as key
 * generation, nonces, salts or one-time pads.
 *
 * 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 `/dev/random` 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
 * [this page](http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html).
 *
 * If you just need a random number, you simply call the g_random_*
 * functions, which will create a globally used #GRand and use the
 * according g_rand_* functions internally. Whenever you need a
 * stream of reproducible random numbers, you better create a
 * #GRand yourself and use the g_rand_* 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 g_rand*_range functions will return high quality equally
 * distributed random numbers, whereas for example the
 * `(g_random_int()%max)` approach often
 * doesn't yield equally distributed numbers.
 *
 * GLib changed the seeding algorithm for the pseudo-random number
 * generator Mersenne Twister, as used by #GRand. This was necessary,
 * because some seeds would yield very bad pseudo-random streams.
 * Also the pseudo-random integers generated by g_rand*_int_range()
 * 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 `G_RANDOM_VERSION` 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 g_rand_* functions.
 **/

G_LOCK_DEFINE_STATIC (global_random);

/* 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.
 * 
 * Returns: 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.
 * 
 * Returns: 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 `/dev/urandom` (if existing) or from the current time
 * (as a fallback).
 *
 * On Windows, the seed is taken from rand_s().
 * 
 * Returns: the new #GRand
 */
GRand* 
g_rand_new (void)
{
  guint32 seed[4];
#ifdef G_OS_UNIX
  static gboolean dev_urandom_exists = TRUE;

  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)
    {
      gint64 now_us = g_get_real_time ();
      seed[0] = now_us / G_USEC_PER_SEC;
      seed[1] = now_us % G_USEC_PER_SEC;
      seed[2] = getpid ();
      seed[3] = getppid ();
    }
#else /* G_OS_WIN32 */
  /* rand_s() is only available since Visual Studio 2005 and
   * MinGW-w64 has a wrapper that will emulate rand_s() if it's not in msvcrt
   */
#if (defined(_MSC_VER) && _MSC_VER >= 1400) || defined(__MINGW64_VERSION_MAJOR)
  gsize i;

  for (i = 0; i < G_N_ELEMENTS (seed); i++)
    rand_s (&seed[i]);
#else
#warning Using insecure seed for random number generation because of missing rand_s() in Windows XP
  GTimeVal now;

  g_get_current_time (&now);
  seed[0] = now.tv_sec;
  seed[1] = now.tv_usec;
  seed[2] = getpid ();
  seed[3] = 0;
#endif

#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.
 *
 * Returns: 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 32 bits of actual entropy for
 * your application.
 *
 * Since: 2.4
 */
void
g_rand_set_seed_array (GRand         *rand,
                       const guint32 *seed,
                       guint          seed_length)
{
  guint 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 an 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].
 *
 * Returns: 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].
 *
 * Returns: a random number
 */
gint32 
g_rand_int_range (GRand  *rand,
                  gint32  begin,
                  gint32  end)
{
  guint32 dist = end - begin;
  guint32 random = 0;

  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:
      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).
 *
 * Returns: a random number
 */
gdouble 
g_rand_double (GRand *rand)
{    
  /* We set all 52 bits after the point for this, not only the first
     32. That's 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).
 *
 * Returns: 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;
}

static GRand *
get_global_random (void)
{
  static GRand *global_random;

  /* called while locked */
  if (!global_random)
    global_random = g_rand_new ();

  return global_random;
}

/**
 * g_random_boolean:
 *
 * Returns a random #gboolean.
 * This corresponds to an unbiased coin toss.
 *
 * Returns: a random #gboolean
 */
/**
 * g_random_int:
 *
 * Return a random #guint32 equally distributed over the range
 * [0..2^32-1].
 *
 * Returns: a random number
 */
guint32
g_random_int (void)
{
  guint32 result;
  G_LOCK (global_random);
  result = g_rand_int (get_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].
 *
 * Returns: a random number
 */
gint32 
g_random_int_range (gint32 begin,
                    gint32 end)
{
  gint32 result;
  G_LOCK (global_random);
  result = g_rand_int_range (get_global_random (), begin, end);
  G_UNLOCK (global_random);
  return result;
}

/**
 * g_random_double:
 *
 * Returns a random #gdouble equally distributed over the range [0..1).
 *
 * Returns: a random number
 */
gdouble 
g_random_double (void)
{
  double result;
  G_LOCK (global_random);
  result = g_rand_double (get_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).
 *
 * Returns: a random number
 */
gdouble 
g_random_double_range (gdouble begin,
                       gdouble end)
{
  double result;
  G_LOCK (global_random);
  result = g_rand_double_range (get_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 g_random_* functions, to @seed.
 */
void
g_random_set_seed (guint32 seed)
{
  G_LOCK (global_random);
  g_rand_set_seed (get_global_random (), seed);
  G_UNLOCK (global_random);
}
