// Exact Rust translation of LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs.
// Source SHA-256: 01957800d5baff9ab13cf22bc496a5506e26f9be194917a94a3558a8456a761c

use libremetaverse_compat_tests::rlv_support::RlvHarness;
use libremetaverse_types::Error;

fn harness() -> RlvHarness {
    RlvHarness::new().expect("RlvService constructor")
}

fn blacklist_behavior(value: &str) -> Result<(), Error> {
    harness()
        .service
        .blacklist()
        .blacklist_behavior(value.into())
}

fn unblacklist_behavior(value: &str) -> Result<(), Error> {
    harness()
        .service
        .blacklist()
        .un_blacklist_behavior(value.into())
}

fn is_blacklisted(value: &str) -> bool {
    harness()
        .service
        .blacklist()
        .is_blacklisted(value.into())
        .unwrap()
}

fn seed(h: &RlvHarness, values: &str) {
    for value in values
        .split(',')
        .map(str::trim)
        .filter(|value| !value.is_empty())
    {
        h.service
            .blacklist()
            .blacklist_behavior(value.into())
            .unwrap();
    }
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.GetBlacklist_EmptyByDefault::test 9bd5c937815547d2d4b9dcfcb5c35d69e224cc4dc256273735c69b8be150c3a8 translated
#[test]
fn blacklist_is_empty_by_default() {
    assert!(
        harness()
            .service
            .blacklist()
            .get_blacklist()
            .unwrap()
            .is_empty()
    );
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.BlacklistBehavior_ValidBehavior_AddsToBlacklist::test dbf7650afeab51abc22fc48881a06e4908f373b6b0077fe58fc4d4e50ea0e0f5 translated
#[test]
fn blacklist_adds_valid_behavior() {
    let h = harness();
    h.service
        .blacklist()
        .blacklist_behavior("testbehavior".into())
        .unwrap();
    let values = h.service.blacklist().get_blacklist().unwrap();
    assert_eq!(values.len(), 1);
    assert!(values.contains(&"testbehavior".into()));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.BlacklistBehavior_CaseInsensitive_NormalizesToLowercase::test dbc4161b4cd5dd7f3609b11f1c6f4f6e1e243b2ba65a444afa67c70cf649c5d3 translated
#[test]
fn blacklist_normalizes_to_lowercase() {
    let h = harness();
    h.service
        .blacklist()
        .blacklist_behavior("TestBehavior".into())
        .unwrap();
    let values = h.service.blacklist().get_blacklist().unwrap();
    assert_eq!(values, vec!["testbehavior"]);
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.BlacklistBehavior_DuplicateBehavior_OnlyAddsOnce::test 53644a5123b90e32f162a9106c945a57d05b17de1a8ab0bf1930283deaf28018 translated
#[test]
fn blacklist_deduplicates_case_insensitively() {
    let h = harness();
    for value in ["testbehavior", "testbehavior", "TESTBEHAVIOR"] {
        h.service
            .blacklist()
            .blacklist_behavior(value.into())
            .unwrap();
    }
    assert_eq!(
        h.service.blacklist().get_blacklist().unwrap(),
        vec!["testbehavior"]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.BlacklistBehavior_NullOrWhitespaceBehavior_ThrowsArgumentException::case:12ae32cb1ec02d01 d9dcd55677740a9a1ffb8b709662060b4c417c10bfc6a361501bb149396dfe17 translated
#[test]
fn blacklist_rejects_empty_behavior() {
    assert_eq!(blacklist_behavior(""), Err(Error::Argument));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.BlacklistBehavior_NullOrWhitespaceBehavior_ThrowsArgumentException::case:52109349dabf6910 d9dcd55677740a9a1ffb8b709662060b4c417c10bfc6a361501bb149396dfe17 translated
#[test]
fn blacklist_rejects_spaces_behavior() {
    assert_eq!(blacklist_behavior("   "), Err(Error::Argument));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.BlacklistBehavior_NullOrWhitespaceBehavior_ThrowsArgumentException::case:729e2865c247816a d9dcd55677740a9a1ffb8b709662060b4c417c10bfc6a361501bb149396dfe17 translated
#[test]
fn blacklist_rejects_tab_behavior() {
    assert_eq!(blacklist_behavior("\t"), Err(Error::Argument));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.BlacklistBehavior_NullOrWhitespaceBehavior_ThrowsArgumentException::case:d7a5e915306d21dc d9dcd55677740a9a1ffb8b709662060b4c417c10bfc6a361501bb149396dfe17 translated
#[test]
fn blacklist_rejects_newline_behavior() {
    assert_eq!(blacklist_behavior("\n"), Err(Error::Argument));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.UnBlacklistBehavior_ExistingBehavior_RemovesFromBlacklist::test 47501ced70145add192d357c6a2647ca4a923bdaab3b1eff1c3857cebc5020db translated
#[test]
fn unblacklist_removes_existing_behavior() {
    let h = harness();
    seed(&h, "testbehavior");
    h.service
        .blacklist()
        .un_blacklist_behavior("testbehavior".into())
        .unwrap();
    assert!(h.service.blacklist().get_blacklist().unwrap().is_empty());
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.UnBlacklistBehavior_CaseInsensitive_RemovesCorrectBehavior::test b5f4a87e8dc603a08a9f1225a35e44962d4240a3e5b9e605c948d19b268ed1bd translated
#[test]
fn unblacklist_is_case_insensitive() {
    let h = harness();
    seed(&h, "TestBehavior");
    h.service
        .blacklist()
        .un_blacklist_behavior("testbehavior".into())
        .unwrap();
    assert!(h.service.blacklist().get_blacklist().unwrap().is_empty());
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.UnBlacklistBehavior_NonExistentBehavior_DoesNothing::test 495314ef0e42ec419b804108907c02ffe9520a1657344f391aa491f91129ecc5 translated
#[test]
fn unblacklist_nonexistent_behavior_does_nothing() {
    let h = harness();
    seed(&h, "existingbehavior");
    h.service
        .blacklist()
        .un_blacklist_behavior("nonexistentbehavior".into())
        .unwrap();
    assert_eq!(
        h.service.blacklist().get_blacklist().unwrap(),
        vec!["existingbehavior"]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.UnBlacklistBehavior_NullOrWhitespaceBehavior_ThrowsArgumentException::case:12ae32cb1ec02d01 9b1e325139b7cec6e99ab40c5ca0e72faa88b95bce521c4ad25ed9370c2dd89f translated
#[test]
fn unblacklist_rejects_empty_behavior() {
    assert_eq!(unblacklist_behavior(""), Err(Error::Argument));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.UnBlacklistBehavior_NullOrWhitespaceBehavior_ThrowsArgumentException::case:52109349dabf6910 9b1e325139b7cec6e99ab40c5ca0e72faa88b95bce521c4ad25ed9370c2dd89f translated
#[test]
fn unblacklist_rejects_spaces_behavior() {
    assert_eq!(unblacklist_behavior("   "), Err(Error::Argument));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.UnBlacklistBehavior_NullOrWhitespaceBehavior_ThrowsArgumentException::case:729e2865c247816a 9b1e325139b7cec6e99ab40c5ca0e72faa88b95bce521c4ad25ed9370c2dd89f translated
#[test]
fn unblacklist_rejects_tab_behavior() {
    assert_eq!(unblacklist_behavior("\t"), Err(Error::Argument));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.UnBlacklistBehavior_NullOrWhitespaceBehavior_ThrowsArgumentException::case:d7a5e915306d21dc 9b1e325139b7cec6e99ab40c5ca0e72faa88b95bce521c4ad25ed9370c2dd89f translated
#[test]
fn unblacklist_rejects_newline_behavior() {
    assert_eq!(unblacklist_behavior("\n"), Err(Error::Argument));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.IsBlacklisted_BlacklistedBehavior_ReturnsTrue::test 2cfeda6f45d63514216d0ffccdee89ee4b7f78e775f43fb12ee78324f9cfde35 translated
#[test]
fn is_blacklisted_returns_true_for_added_behavior() {
    let h = harness();
    seed(&h, "testbehavior");
    assert!(
        h.service
            .blacklist()
            .is_blacklisted("testbehavior".into())
            .unwrap()
    );
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.IsBlacklisted_CaseInsensitive_ReturnsTrue::test 1b4c6ed072b97dd9abcc0f730533691d8a65122d1839d40736e98a0f5c43f07d translated
#[test]
fn is_blacklisted_is_case_insensitive() {
    let h = harness();
    seed(&h, "TestBehavior");
    for value in ["testbehavior", "TESTBEHAVIOR", "TestBehavior"] {
        assert!(h.service.blacklist().is_blacklisted(value.into()).unwrap());
    }
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.IsBlacklisted_NonBlacklistedBehavior_ReturnsFalse::test f4cc9018c5d111b06dc8c2ce0d6ed042eb063331f35ef1665e65f4d8606d3cd3 translated
#[test]
fn is_blacklisted_returns_false_for_missing_behavior() {
    let h = harness();
    seed(&h, "existingbehavior");
    assert!(
        !h.service
            .blacklist()
            .is_blacklisted("nonexistentbehavior".into())
            .unwrap()
    );
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.IsBlacklisted_NullOrWhitespaceBehavior_ReturnsFalse::case:12ae32cb1ec02d01 ca0126a6bc1cc4ca73fdfe939ad4c9dbf1e35da741c4ea46eb3c16687730a1fa translated
#[test]
fn is_blacklisted_returns_false_for_empty_behavior() {
    assert!(!is_blacklisted(""));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.IsBlacklisted_NullOrWhitespaceBehavior_ReturnsFalse::case:52109349dabf6910 ca0126a6bc1cc4ca73fdfe939ad4c9dbf1e35da741c4ea46eb3c16687730a1fa translated
#[test]
fn is_blacklisted_returns_false_for_spaces_behavior() {
    assert!(!is_blacklisted("   "));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.IsBlacklisted_NullOrWhitespaceBehavior_ReturnsFalse::case:729e2865c247816a ca0126a6bc1cc4ca73fdfe939ad4c9dbf1e35da741c4ea46eb3c16687730a1fa translated
#[test]
fn is_blacklisted_returns_false_for_tab_behavior() {
    assert!(!is_blacklisted("\t"));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.IsBlacklisted_NullOrWhitespaceBehavior_ReturnsFalse::case:d7a5e915306d21dc ca0126a6bc1cc4ca73fdfe939ad4c9dbf1e35da741c4ea46eb3c16687730a1fa translated
#[test]
fn is_blacklisted_returns_false_for_newline_behavior() {
    assert!(!is_blacklisted("\n"));
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.GetBlacklist_MultipleItems_ReturnsOrderedCollection::test db9bd586b7a4f79ffd2d2c48c8131ccd4bd44d8de444696e9a7c53614ef37ed5 translated
#[test]
fn get_blacklist_returns_ordered_collection() {
    let h = harness();
    seed(&h, "zebra,alpha,beta,charlie");
    assert_eq!(
        h.service.blacklist().get_blacklist().unwrap(),
        vec!["alpha", "beta", "charlie", "zebra"]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.GetBlacklist_ReturnsImmutableCopy::test 64db7441c81ea4f0d2e52e79b479cf658fbd2c2d1d23b918edcfa03db1233a3a translated
#[test]
fn get_blacklist_returns_independent_copy() {
    let h = harness();
    seed(&h, "testbehavior");
    let first = h.service.blacklist().get_blacklist().unwrap();
    seed(&h, "anotherbehavior");
    let second = h.service.blacklist().get_blacklist().unwrap();
    assert_eq!(first, vec!["testbehavior"]);
    assert_eq!(second, vec!["anotherbehavior", "testbehavior"]);
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.BlacklistWorkflow_AddMultipleBehaviors_WorksCorrectly::test 75d84bd0b26b16821ba107bef2bbb2ae58a2726496a757092b24dff6170f8872 translated
#[test]
fn blacklist_workflow_adds_and_removes_behaviors() {
    let h = harness();
    seed(&h, "sendim,recvim,tpto,fly");
    for value in ["sendim", "recvim", "tpto", "fly"] {
        assert!(h.service.blacklist().is_blacklisted(value.into()).unwrap());
    }
    h.service
        .blacklist()
        .un_blacklist_behavior("sendim".into())
        .unwrap();
    h.service
        .blacklist()
        .un_blacklist_behavior("fly".into())
        .unwrap();
    assert!(
        !h.service
            .blacklist()
            .is_blacklisted("sendim".into())
            .unwrap()
    );
    assert!(
        h.service
            .blacklist()
            .is_blacklisted("recvim".into())
            .unwrap()
    );
    assert!(h.service.blacklist().is_blacklisted("tpto".into()).unwrap());
    assert!(!h.service.blacklist().is_blacklisted("fly".into()).unwrap());
    assert_eq!(
        h.service.blacklist().get_blacklist().unwrap(),
        vec!["recvim", "tpto"]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.SeedBlacklist_IntegrationWithRestrictionsBase_WorksCorrectly::test f7347786e3a579dc0102dc20fb73823362866ea71658777aa6835a28a58daea9 translated
#[test]
fn seed_blacklist_adds_each_comma_separated_behavior() {
    let h = harness();
    seed(&h, "sendim,recvim,tpto");
    for value in ["sendim", "recvim", "tpto"] {
        assert!(h.service.blacklist().is_blacklisted(value.into()).unwrap());
    }
    assert!(!h.service.blacklist().is_blacklisted("fly".into()).unwrap());
    assert_eq!(h.service.blacklist().get_blacklist().unwrap().len(), 3);
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.SeedBlacklist_EmptyString_ResultsInEmptyBlacklist::test 63555a93fbcc2b7691fdd2b79fe0db8cb305beef2c153b80f0040ba8f4f7117e translated
#[test]
fn seed_blacklist_empty_string_adds_nothing() {
    let h = harness();
    seed(&h, "");
    assert!(h.service.blacklist().get_blacklist().unwrap().is_empty());
}

// parity-case: LibreMetaverse.Tests/RLV/RlvBlacklistTests.cs::RlvBlacklistTests.SeedBlacklist_WithSpaces_HandlesCorrectly::test ddd764a51e179fa6c349ab2a62bdedde1e62e4ff2ae33aa41a4ebb2359974404 translated
#[test]
fn seed_blacklist_trims_spaces() {
    let h = harness();
    seed(&h, "sendim, recvim , tpto");
    for value in ["sendim", "recvim", "tpto"] {
        assert!(h.service.blacklist().is_blacklisted(value.into()).unwrap());
    }
    assert_eq!(h.service.blacklist().get_blacklist().unwrap().len(), 3);
}
