// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use glam::Vec2;

use super::*;

#[test]
fn truncates_correctly() {
	let updates = get_updates();
	assert_eq!(u64::from_le_bytes(updates.serialise(9999).unwrap()[..8].try_into().unwrap()), 69);
	assert_eq!(u64::from_le_bytes(updates.serialise(24).unwrap()[..8].try_into().unwrap()), 69 + 1);
	assert_eq!(u64::from_le_bytes(updates.serialise(20).unwrap()[..8].try_into().unwrap()), 69 + 3);
	assert_eq!(u64::from_le_bytes(updates.serialise(16).unwrap()[..8].try_into().unwrap()), 69 + 6);
	assert_eq!(u64::from_le_bytes(updates.serialise(12).unwrap()[..8].try_into().unwrap()), 69 + 10);
}

#[test]
fn is_none_small() {
	let updates = get_updates();
	for i in 0..=11 {
		assert!(updates.serialise(i).is_none());
	}
}

fn get_updates() -> PlayerBulkUpdate {
	let mut updates = PlayerBulkUpdate::new(69);
	for i in 1..=5 {
		updates.updates.push((PlayerUpdate::default(), i));
	}
	updates
}

#[test]
fn serde_same_results() {
	for _ in 0..5000 {
		let sequence_number = rand::random::<u64>();
		let count = rand::random::<usize>() % 20;

		let mut bulk_update = PlayerBulkUpdate::new(sequence_number);
		for _ in 0..count {
			let dir = Direction::from(rand::random::<Vec2>());
			let input_state = InputState::from_bits(rand::random::<u8>());
			let count = rand::random::<u8>();
			bulk_update.updates.push((PlayerUpdate { dir, input_state }, count));
		}

		// You get the same result back after serialising and deserialising
		if let Some(data) = bulk_update.serialise(usize::MAX) {
			assert_eq!(bulk_update, PlayerBulkUpdate::deserialise(&data).unwrap());
		}

		// With a bit of truncation tests some properties
		let limit = rand::random::<usize>() % 256;
		if let Some(data) = bulk_update.serialise(limit) {
			let smaller_bulk_update = PlayerBulkUpdate::deserialise(&data).unwrap();
			assert!(smaller_bulk_update.updates.len() <= bulk_update.updates.len());
			assert!(smaller_bulk_update.sequence_number >= bulk_update.sequence_number);

			// With the same limit you should get it back again
			if let Some(data) = smaller_bulk_update.serialise(limit) {
				assert_eq!(smaller_bulk_update, PlayerBulkUpdate::deserialise(&data).unwrap());
			}
		}
	}
}
