/*
 * Very simple prng to allow for randomized tests with reproducable
 * results.
 *
 * Copyright (C) 2012 by Open Source Routing.
 * Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
 *
 * This file is part of Quagga
 *
 * Quagga is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * Quagga 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Quagga; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#include <zebra.h>

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "prng.h"

struct prng
{
  unsigned long long state1;
  unsigned long long state2;
};

static char
prng_bit(struct prng *prng)
{
  prng->state1 *= 2416;
  prng->state1 += 374441;
  prng->state1 %= 1771875;

  if (prng->state1 % 2)
    {
      prng->state2 *= 84589;
      prng->state2 += 45989;
      prng->state2 %= 217728;
    }

  return prng->state2 % 2;
}

struct prng*
prng_new(unsigned long long seed)
{
  struct prng *rv = calloc(sizeof(*rv), 1);
  assert(rv);

  rv->state1 = rv->state2 = seed;

  return rv;
}

unsigned int
prng_rand(struct prng *prng)
{
  unsigned int i, rv = 0;

  for (i = 0; i < 32; i++)
    {
      rv |= prng_bit(prng);
      rv <<= 1;
    }
  return rv;
}

const char *
prng_fuzz(struct prng *prng,
          const char *string,
          const char *charset,
          unsigned int operations)
{
  static char buf[256];
  unsigned int charset_len;
  unsigned int i;
  unsigned int offset;
  unsigned int op;
  unsigned int character;

  assert(strlen(string) < sizeof(buf));

  strncpy(buf, string, sizeof(buf));
  charset_len = strlen(charset);

  for (i = 0; i < operations; i++)
    {
      offset = prng_rand(prng) % strlen(buf);
      op = prng_rand(prng) % 3;

      switch (op)
        {
        case 0:
          /* replace */
          character = prng_rand(prng) % charset_len;
          buf[offset] = charset[character];
          break;
        case 1:
          /* remove */
          memmove(buf + offset, buf + offset + 1, strlen(buf) - offset);
          break;
        case 2:
          /* insert */
          assert(strlen(buf) + 1 < sizeof(buf));

          memmove(buf + offset + 1, buf + offset, strlen(buf) + 1 - offset);
          character = prng_rand(prng) % charset_len;
          buf[offset] = charset[character];
          break;
        }
    }
  return buf;
}

void
prng_free(struct prng *prng)
{
  free(prng);
}
