// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT
//
// Imported from snmalloc 4f9d991449380ed7d881a25ba02cc5668c1ff394.

#pragma once

#include <cstdint>
#include <cstdlib>
#include <debug.hh>
#include <initializer_list>

namespace ds::xoroshiro
{

	namespace detail
	{
		using Debug = ConditionalDebug<false, "xoroshiro">;

		/**
		 * The xoroshiro+ (not ++) generator(s) of Blackman and Vigna's
		 * Scrambled Linear Pseudorandom Number Generators
		 * (https://arxiv.org/abs/1805.01407, Figure 1).
		 *
		 * This spelling is parameterized on the type of the two state
		 * variables used internally (State), the type of each sample (Result),
		 * and the seed state values (A, B, C).
		 */
		template<typename State,
		         typename Result,
		         State A,
		         State B,
		         State C,
		         State Jump0     = 0,
		         State Jump1     = 0,
		         State LongJump0 = 0,
		         State LongJump1 = 0>
		class XorOshiro
		{
			private:
			static constexpr unsigned StateBits  = 8 * sizeof(State);
			static constexpr unsigned ResultBits = 8 * sizeof(Result);

			static_assert(StateBits >= ResultBits,
			              "State must have at least as many bits as Result");

			/* Parameters must be valid shifts */
			static_assert(0 <= A && A <= StateBits);
			static_assert(0 <= B && B <= StateBits);
			static_assert(0 <= C && C <= StateBits);

			State x;
			State y;

			static inline State rotl(State x, State k)
			{
				return (x << k) | (x >> (StateBits - k));
			}

			void jump(State jump0, State jump1)
			{
				const State Jump[] = {jump0, jump1};
				uint64_t    s0     = 0;
				uint64_t    s1     = 0;
				for (int i : {0, 1})
				{
					for (int b = 0; b < 64; b++)
					{
						if (Jump[i] & uint64_t(1) << b)
						{
							s0 ^= x;
							s1 ^= y;
						}
						next();
					}
				}
				x = s0;
				y = s1;
			}

			public:
			XorOshiro(State x = 5489, State y = 0) : x(x), y(y)
			{
				// If both zero, then this does not work
				Debug::Invariant((x != 0) || (y != 0),
				                 "Invalid state, both x and y are zero");

				next();
			}

			void set_state(State nx, State ny = 0)
			{
				// If both zero, then this does not work
				Debug::Invariant((nx != 0) || (ny != 0),
				                 "Invalid state, both nx and ny are zero");

				x = nx;
				y = ny;
				next();
			}

			Result next()
			{
				State oldX = x;
				State oldY = y;
				State r    = x + y;
				y ^= x;
				x = rotl(x, A) ^ y ^ (y << B);
				y = rotl(y, C);
				// If both zero, then this does not work
				Debug::Invariant((x != 0) || (y != 0),
				                 "Invalid state, both x and y are zero after "
				                 "next() with x: {}, y: {}",
				                 oldX,
				                 oldY);
				return r >> (StateBits - ResultBits);
			}

			Result operator()()
			{
				return next();
			}

			/**
			 * Jump.  If supported, this is equivalent to 2^64 calls to next().
			 */
			void jump() requires(Jump0 != 0) && (Jump1 != 0)
			{
				jump(Jump0, Jump1);
			}

			/**
			 * Jump a *really* long way.  If supported, this is equivalent to
			 * 2^96 calls to next().
			 */
			void long_jump() requires(LongJump0 != 0) && (LongJump1 != 0)
			{
				jump(LongJump0, LongJump1);
			}
		};
	} // namespace detail

	/**
	 * xoroshiro128+ with 64-bit output using the 2018 parameters.
	 *
	 * Parameters (including jump parameters) from:
	 * https://prng.di.unimi.it/xoroshiro128plus.c
	 */
	using P128R64 = detail::XorOshiro<uint64_t,
	                                  uint64_t,
	                                  24,
	                                  16,
	                                  37,
	                                  0xdf900294d8f554a5,
	                                  0x170865df4b3201fc,
	                                  0xd2a98b26625eee7b,
	                                  0xdddf9b1090aa7ac1>;

	/**
	 * xoroshiro128+ with 32-bit output using the 2018 parameters.
	 *
	 * Parameters as per P128R64, above.
	 */
	using P128R32 = detail::XorOshiro<uint64_t, uint32_t, 24, 16, 37>;

	/**
	 * A "xoroshiro64+" with 32-bit outputs.
	 *
	 * As per Sebastino Vigna himself, writing in
	 * https://groups.google.com/g/prng/c/Ll-KDIbpO8k/m/bfHK4FlUCwAJ, these
	 * parameters are one of may full-period triples.
	 */
	using P64R32 = detail::XorOshiro<uint32_t, uint32_t, 27, 7, 20>;

	/**
	 * A "xoroshiro64+" with 16-bit outputs.
	 *
	 * Parameters as per P64R32, above.
	 */
	using P64R16 = detail::XorOshiro<uint32_t, uint16_t, 27, 7, 20>;

	/**
	 * A "xoroshiro32+" with 16-bit outputs.
	 *
	 * Parameters as per the Parallax Propeller 2 PRNG (discarding the "++"
	 * variant's fourth parameter "R").  See
	 * https://forums.parallax.com/discussion/comment/1448894 .
	 */
	using P32R16 = detail::XorOshiro<uint16_t, uint16_t, 13, 5, 10>;

	/**
	 * A "xoroshiro32+" with 16-bit outputs.
	 *
	 * Parameters as per P32R16, above.
	 */
	using P32R8 = detail::XorOshiro<uint16_t, uint8_t, 13, 5, 10>;

	/**
	 * A "xoroshiro16+" with 8-bit outputs.
	 *
	 * As per Sebastino Vigna himself, writing in
	 * https://groups.google.com/g/prng/c/MWJjq11zRis/m/7nM_cwRzAQAJ , the
	 * parameters are one of may full-period triples, but "There are no good
	 * 16-bit generators".
	 */
	using P16R8 = detail::XorOshiro<uint8_t, uint8_t, 4, 7, 3>;
} // namespace ds::xoroshiro
