#![cfg(feature = "serde")]

use btree_indexmap::{BTreeIndexMap, BTreeIndexMultiMap, BTreeIndexMultiSet, BTreeIndexSet};

// ── BTreeIndexMap ────────────────────────────────────────────────────────────

#[test]
fn map_serialize() {
	let mut map = BTreeIndexMap::new();
	map.insert("b".to_string(), 2);
	map.insert("a".to_string(), 1);

	let json = serde_json::to_string(&map).unwrap();
	assert_eq!(json, r#"{"b":2,"a":1}"#);
}

#[test]
fn map_round_trip() {
	let mut map = BTreeIndexMap::new();
	map.insert("b".to_string(), 2);
	map.insert("a".to_string(), 1);

	let json = serde_json::to_string(&map).unwrap();
	let round_tripped: BTreeIndexMap<String, i32> = serde_json::from_str(&json).unwrap();

	assert_eq!(map, round_tripped);
	// Insertion order is preserved.
	assert_eq!(
		round_tripped.as_entries(),
		[("b".to_string(), 2), ("a".to_string(), 1)]
	);
}

// ── BTreeIndexMultiMap ───────────────────────────────────────────────────────

#[test]
fn multi_map_round_trip_preserves_duplicate_keys() {
	let mut map = BTreeIndexMultiMap::new();
	map.push_back("a".to_string(), 1);
	map.push_back("a".to_string(), 2);
	map.push_back("b".to_string(), 3);

	let json = serde_json::to_string(&map).unwrap();
	assert_eq!(json, r#"{"a":1,"a":2,"b":3}"#);

	let round_tripped: BTreeIndexMultiMap<String, i32> = serde_json::from_str(&json).unwrap();

	assert_eq!(map, round_tripped);
	assert_eq!(round_tripped.key_occurences("a"), 2);
	assert_eq!(
		round_tripped.as_entries(),
		[
			("a".to_string(), 1),
			("a".to_string(), 2),
			("b".to_string(), 3)
		]
	);
}

// ── BTreeIndexSet ────────────────────────────────────────────────────────────

#[test]
fn set_serialize() {
	let mut set = BTreeIndexSet::new();
	set.insert("b".to_string());
	set.insert("a".to_string());

	let json = serde_json::to_string(&set).unwrap();
	assert_eq!(json, r#"["b","a"]"#);
}

#[test]
fn set_round_trip() {
	let mut set = BTreeIndexSet::new();
	set.insert("b".to_string());
	set.insert("a".to_string());

	let json = serde_json::to_string(&set).unwrap();
	let round_tripped: BTreeIndexSet<String> = serde_json::from_str(&json).unwrap();

	assert_eq!(set, round_tripped);
	assert_eq!(round_tripped.as_slice(), ["b".to_string(), "a".to_string()]);
}

// ── BTreeIndexMultiSet ───────────────────────────────────────────────────────

#[test]
fn multi_set_round_trip_preserves_duplicate_values() {
	let mut set = BTreeIndexMultiSet::new();
	set.push_back("a".to_string());
	set.push_back("a".to_string());
	set.push_back("b".to_string());

	let json = serde_json::to_string(&set).unwrap();
	assert_eq!(json, r#"["a","a","b"]"#);

	let round_tripped: BTreeIndexMultiSet<String> = serde_json::from_str(&json).unwrap();

	assert_eq!(set, round_tripped);
	assert_eq!(round_tripped.count("a"), 2);
	assert_eq!(
		round_tripped.as_slice(),
		["a".to_string(), "a".to_string(), "b".to_string()]
	);
}
