// Copyright (c) 2026 Zack Puhl <github@xmit.xyz>. All rights reserved.
// Use of this source code is governed by the MIT license
// a copy of which can be found in the LICENSE_STDLIB file.
module splitmix_tests @test;

import std::math::random;

// Source: https://sourceforge.net/p/xoshiroprng-net/code/ci/default/tree/xTests/TestNativeOutput.cs
fn void simple_next()
{
	SplitMix64 sm64;
	const ulong[] EXPECTED_0 = {
		16294208416658607535,
		7960286522194355700,
		487617019471545679,
		17909611376780542444,
	};
	foreach (e : EXPECTED_0) test::eq(sm64.next_long(), e);

	sm64 = (ulong)long::max;
	const ulong[] EXPECTED_MAX = {
		3055647633038352039,
		17441316833444690247,
		17011665146503905680,
		2314904739866303483,
	};
	foreach (e : EXPECTED_MAX) test::eq(sm64.next_long(), e);

	sm64 = (ulong)long::min;
	const ulong[] EXPECTED_MIN = {
		5196802822362493915,
		14154714916085338130,
		7036458801432265024,
		6426116064599561977,
	};
	foreach (e : EXPECTED_MIN) test::eq(sm64.next_long(), e);
}

// Source: https://shadow.github.io/docs/rust/src/rand_xoshiro/splitmix64.rs.html
fn void simple_next_ext()
{
	SplitMix64 sm64 = 1477776061723855037;
	const ulong[] EXPECTED = {
		1985237415132408290, 2979275885539914483, 13511426838097143398, 8488337342461049707,
		15141737807933549159, 17093170987380407015, 16389528042912955399, 13177319091862933652,
		10841969400225389492, 17094824097954834098, 3336622647361835228, 9678412372263018368,
		11111587619974030187, 7882215801036322410, 5709234165213761869, 7799681907651786826,
		4616320717312661886, 4251077652075509767, 7836757050122171900, 5054003328188417616,
		12919285918354108358, 16477564761813870717, 5124667218451240549, 18099554314556827626,
		7603784838804469118, 6358551455431362471, 3037176434532249502, 3217550417701719149,
		9958699920490216947, 5965803675992506258, 12000828378049868312, 12720568162811471118,
		245696019213873792, 8351371993958923852, 14378754021282935786, 5655432093647472106,
		5508031680350692005, 8515198786865082103, 6287793597487164412, 14963046237722101617,
		3630795823534910476, 8422285279403485710, 10554287778700714153, 10871906555720704584,
		8659066966120258468, 9420238805069527062, 10338115333623340156, 13514802760105037173,
		14635952304031724449, 15419692541594102413,
	};
	foreach (e : EXPECTED) test::eq(sm64.next_long(), e);
	sm64 = 1477776061723855037;
	foreach (e : EXPECTED) test::eq(sm64.next_int(), (uint)e);   // ensure truncation works as expected
}