/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

//mod hash256;

use hash256::HASH256;

const RAND_NK: usize=21;
const RAND_NJ: usize=6;
const RAND_NV: usize=8;

pub struct RAND {
	ira: [u32;RAND_NK],  /* random number...   */
	rndptr: usize,
	borrow: u32,
	pool_ptr: usize,
	pool: [u8;32]
}

impl RAND {

	pub fn new() -> RAND {
		RAND {
			ira: [0;RAND_NK],
			rndptr:0,
			borrow: 0,
			pool_ptr:0,
			pool:[0;32]
		}
	}

	pub fn clean(&mut self) {
		self.pool_ptr=0; self.rndptr=0;
		for i in 0..32 {self.pool[i]=0}
		for i in 0..RAND_NK {self.ira[i]=0}
		self.borrow=0;		
	}

	fn sbrand(&mut self) -> u32 { /* Marsaglia & Zaman random number generator */
		self.rndptr+=1;
		if self.rndptr<RAND_NK {return self.ira[self.rndptr]}
		self.rndptr=0;
		let mut k=RAND_NK-RAND_NJ;
		for i in 0..RAND_NK { /* calculate next NK values */
			if k==RAND_NK {k=0}
			let t=self.ira[k];
			let pdiff=t.wrapping_sub(self.ira[i]).wrapping_sub(self.borrow);
			if pdiff<t {self.borrow=0}
			if pdiff>t {self.borrow=1}
			self.ira[i]=pdiff;
			k+=1;
		}
		return self.ira[0];
	}

	fn sirand(&mut self,seed: u32) {
		let mut m: u32=1;
		let mut sd=seed;
		self.borrow=0;
		self.rndptr=0;
		self.ira[0]^=sd;
		for i in 1..RAND_NK { /* fill initialisation vector */
			let inn=(RAND_NV*i)%RAND_NK;
			self.ira[inn]^=m;      /* note XOR */
			let t=m;
			m=sd.wrapping_sub(m);
			sd=t;
		}
		for _ in 0..10000 {self.sbrand();} /* "warm-up" & stir the generator */
	}

	fn fill_pool(&mut self) {
		let mut sh=HASH256::new();
		for _ in 0..128 {sh.process((self.sbrand()&0xff) as u8)}
		let w=sh.hash();
		for i in 0..32 {self.pool[i]=w[i]}
		self.pool_ptr=0;
	}

	fn pack(b: [u8;4]) -> u32 { /* pack 4 bytes into a 32-bit Word */
		return ((((b[3] as u32))&0xff)<<24)|(((b[2] as u32)&0xff)<<16)|(((b[1] as u32)&0xff)<<8)|((b[0] as u32)&0xff);
	}

/* Initialize RNG with some real entropy from some external source */
	pub fn seed(&mut self,rawlen: usize,raw: &[u8]) { /* initialise from at least 128 byte string of raw random entropy */
		let mut b: [u8;4]=[0;4];
		let mut sh=HASH256::new();
		self.pool_ptr=0;

		for i in 0..RAND_NK {self.ira[i]=0}
		if rawlen>0 {
			for i in 0..rawlen {
				sh.process(raw[i]);
			}
			let digest=sh.hash();

/* initialise PRNG from distilled randomness */

			for i in 0..8  {
				b[0]=digest[4*i]; b[1]=digest[4*i+1]; b[2]=digest[4*i+2]; b[3]=digest[4*i+3];
				self.sirand(RAND::pack(b));
			}
		}
		self.fill_pool();
	}	

/* get random byte */
	pub fn getbyte(&mut self) -> u8 { 
		let r=self.pool[self.pool_ptr];
		self.pool_ptr+=1;
		if self.pool_ptr>=32 {self.fill_pool()}
		return (r&0xff) as u8;
	}
}

/* test main program */
/*
fn main() {
	let mut raw : [u8;100]=[0;100];
	let mut rng=RAND::new();

	rng.clean();
	for i in 0..100 {raw[i]=i as u8}

	rng.seed(100,&raw);
 
	for _ in 0..1000 {
		print!("{:03} ",rng.getbyte());
	}
}
*/
