// Exact Rust translations of the simple RLV permission restrictions.

use libremetaverse_compat_tests::block_on;
use libremetaverse_compat_tests::rlv_support::{RlvHarness, guid};
use libremetaverse_rlv::{
    RlvPermissionsService, RlvPermissionsServiceObjectLocation as ObjectLocation,
    RlvPermissionsServiceTouchLocation as TouchLocation,
};
use libremetaverse_types::Error;

fn check_simple(
    command: &str,
    permission: fn(&RlvPermissionsService) -> Result<bool, Error>,
) -> [bool; 2] {
    let h = RlvHarness::new().expect("RlvService constructor");
    block_on(h.process(&format!("@{command}=n"))).unwrap();
    let restricted = permission(&h.service.permissions()).unwrap();
    block_on(h.process(&format!("@{command}=y"))).unwrap();
    [restricted, permission(&h.service.permissions()).unwrap()]
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/AllowIdleRestrictionTests.cs::AllowIdleRestrictionTests.CanAllowIdle::test 6278bb1a70f024f687080cb8e8a56bbc923f679fb4adb61c6c91c3397a3de7fc translated
#[test]
fn allow_idle_restriction() {
    assert_eq!(
        check_simple("allowIdle", RlvPermissionsService::can_allow_idle),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/AlwaysRunRestrictionTests.cs::AlwaysRunRestrictionTests.CanAlwaysRun::test 9c0a34e0960e3e2a834ccfc1c129a1f5a8f8c6cfd30b322671b4e5c4cd25a24c translated
#[test]
fn always_run_restriction() {
    assert_eq!(
        check_simple("alwaysRun", RlvPermissionsService::can_always_run),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ChatNormalTests.cs::ChatNormalTests.CanChatNormal::test 9a23c49327636e769c7ff2688a0649d441f3531406e8f51e152ec7186a312287 translated
#[test]
fn chat_normal_restriction() {
    assert_eq!(
        check_simple("chatNormal", RlvPermissionsService::can_chat_normal),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ChatShoutRestrictionTests.cs::ChatShoutRestrictionTests.CanChatShout::test 493e1dd87afaaa7f8183e677df5c32d00f150ffcdd53f9afad8684672837aa28 translated
#[test]
fn chat_shout_restriction() {
    assert_eq!(
        check_simple("chatShout", RlvPermissionsService::can_chat_shout),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ChatWhisperRestrictionTests.cs::ChatWhisperRestrictionTests.CanChatWhisper::test 67c5d2cb8b3e9424fbcf08378c2a28368fe07aa83ec028df7cf88b91576d3e9f translated
#[test]
fn chat_whisper_restriction() {
    assert_eq!(
        check_simple("chatWhisper", RlvPermissionsService::can_chat_whisper),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/DefaultWearRestrictionTests.cs::DefaultWearRestrictionTests.CanDefaultWear::test 64eef4c82d1c5a21bc923cfd44616ddc1a5e6403a9a1c5ad6bd2e5ee06e9704c translated
#[test]
fn default_wear_restriction() {
    assert_eq!(
        check_simple("defaultWear", RlvPermissionsService::can_default_wear),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/FlyRestrictionTests.cs::FlyRestrictionTests.CanFly::test 5f60149edccece6b8a6827bbdc6f593ffd863961c13b506f1171aa0cf37fd5b7 translated
#[test]
fn fly_restriction() {
    assert_eq!(
        check_simple("fly", RlvPermissionsService::can_fly),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/InteractRestrictionTests.cs::InteractRestrictionTests.CanInteract::test 935d319e07b613ba39b06db30cfd18306670f7dc97186db38c0374c3aac6901e translated
#[test]
fn interact_restriction() {
    assert_eq!(
        check_simple("interact", RlvPermissionsService::can_interact),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/InteractRestrictionTests.cs::InteractRestrictionTests.CanInteract_default::test 53b9d7f7cfd63a10538060624f81b7a6b1754a7462c230671ed909698dd18923 translated
#[test]
fn interact_restriction_blocks_touch_edit_rez_and_sit() {
    let h = RlvHarness::new().unwrap();
    block_on(h.process("@interact=n")).unwrap();
    let permissions = h.service.permissions();
    let object = guid("00000000-0000-4000-8000-000000000000");
    let user = Some(Some(guid("55555555-5555-4555-8555-555555555555")));
    for (location, user, distance) in [
        (TouchLocation::AttachedSelf, None, None),
        (TouchLocation::AttachedOther, user, None),
        (TouchLocation::RezzedInWorld, None, Some(Some(5.0))),
        (TouchLocation::Hud, None, None),
    ] {
        assert!(
            !permissions
                .can_touch(location, object, user, distance)
                .unwrap()
        );
    }
    for location in [
        ObjectLocation::Attached,
        ObjectLocation::RezzedInWorld,
        ObjectLocation::Hud,
    ] {
        assert!(!permissions.can_edit(location, Some(Some(object))).unwrap());
    }
    assert!(!permissions.can_rez().unwrap());
    assert!(!permissions.can_sit().unwrap());
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/JumpRestrictionTests.cs::JumpRestrictionTests.CanJump::test 104374c66e6748d101b69ed5343d9972f29e937305cb17f90244ffa74fc7ed35 translated
#[test]
fn jump_restriction() {
    assert_eq!(
        check_simple("jump", RlvPermissionsService::can_jump),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/RezRestrictionTests.cs::RezRestrictionTests.CanRez::test 5cae348cc241a884803692031c0af4f33fb3a2ce8331129a9866c5364599eccb translated
#[test]
fn rez_restriction() {
    assert_eq!(
        check_simple("rez", RlvPermissionsService::can_rez),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/SendChatRestrictionTests.cs::SendChatRestrictionTests.CanSendChat::test 36cfbe5123b4b37ee43f0b4ba6453ebbe2754960825b1a8481e77e4f3a0e8015 translated
#[test]
fn send_chat_restriction() {
    assert_eq!(
        check_simple("sendChat", RlvPermissionsService::can_send_chat),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/SendChatRestrictionTests.cs::SendChatRestrictionTests.CanChat_SendChatRestriction::test 793a31da070038e90c41e4bdb1161daaf51376617a7444867f19c7125ad34313 translated
#[test]
fn send_chat_restriction_preserves_slash_messages_and_private_channels() {
    let h = RlvHarness::new().unwrap();
    block_on(h.process("@sendchat=n")).unwrap();
    let permissions = h.service.permissions();
    assert!(!permissions.can_chat(0, "Hello".into()).unwrap());
    assert!(permissions.can_chat(0, "/me says Hello".into()).unwrap());
    assert!(permissions.can_chat(0, "/ something?".into()).unwrap());
    assert!(
        !permissions
            .can_chat(0, "/me says Hello ^_^".into())
            .unwrap()
    );
    assert!(permissions.can_chat(5, "Hello".into()).unwrap());
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/SendGestureRestrictionTests.cs::SendGestureRestrictionTests.CanSendGesture::test 91367110c04e3c6ad173f56f209a166d828560850d3d084893e899bcc756428a translated
#[test]
fn send_gesture_restriction() {
    assert_eq!(
        check_simple("sendGesture", RlvPermissionsService::can_send_gesture),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/SetDebugRestrictionTests.cs::SetDebugRestrictionTests.CanSetDebug::test d4fb9da4879ef8d1be115e00b7a8de959fd58e32722bc9e2985bca8e97dd2ce3 translated
#[test]
fn set_debug_restriction() {
    assert_eq!(
        check_simple("setDebug", RlvPermissionsService::can_set_debug),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/SetEnvRestrictionTests.cs::SetEnvRestrictionTests.CanSetEnv::test bb4c82afd643d267264467282cdfe09095c804079e73dd15179e1aa0b063c08f translated
#[test]
fn set_env_restriction() {
    assert_eq!(
        check_simple("setEnv", RlvPermissionsService::can_set_env),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/SetGroupRestrictionTests.cs::SetGroupRestrictionTests.CanSetGroup::test 9d89210cbc5c188985a535ae045e44d296c796f700d4a1e2b7b4d75345cc4a6d translated
#[test]
fn set_group_restriction() {
    assert_eq!(
        check_simple("setGroup", RlvPermissionsService::can_set_group),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ShowInvRestrictionTests.cs::ShowInvRestrictionTests.CanShowInv::test b7c8bb7ad9d2c02c1c0168531c8ac0636885817a40b13bc006f4f5b20d28591c translated
#[test]
fn show_inventory_restriction() {
    assert_eq!(
        check_simple("showInv", RlvPermissionsService::can_show_inv),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ShowLocRestrictionTests.cs::ShowLocRestrictionTests.CanShowLoc::test a8b154f2db967ab72781f31dcd7701d204f66ece1ef95a30cc67d788c78da617 translated
#[test]
fn show_location_restriction() {
    assert_eq!(
        check_simple("showLoc", RlvPermissionsService::can_show_loc),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ShowMiniMapRestrictionTests.cs::ShowMiniMapRestrictionTests.CanShowMiniMap::test da901135b533aee1b025cf5dd925e857b4734ea00770ced4518f501453ea9736 translated
#[test]
fn show_mini_map_restriction() {
    assert_eq!(
        check_simple("showMiniMap", RlvPermissionsService::can_show_mini_map),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ShowNearbyRestrictionTests.cs::ShowNearbyRestrictionTests.CanShowNearby::test 4faa79795b1143934efbd8ebea7a926b270dd5d1e69f8a64f496063d570d868d translated
#[test]
fn show_nearby_restriction() {
    assert_eq!(
        check_simple("showNearby", RlvPermissionsService::can_show_nearby),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ShowWorldMapRestrictionTests.cs::ShowWorldMapRestrictionTests.CanShowWorldMap::test da16f247df929f83ed21377869790c00cb5922fa6086da3787e90570f5684f67 translated
#[test]
fn show_world_map_restriction() {
    assert_eq!(
        check_simple("showWorldMap", RlvPermissionsService::can_show_world_map),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/SitRestrictionTests.cs::SitRestrictionTests.CanSit::test 813906dbfd09bb02c129a794f40a2f5dcda6e73d232e167359a6360a350fa4b4 translated
#[test]
fn sit_restriction() {
    assert_eq!(
        check_simple("sit", RlvPermissionsService::can_sit),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/StandTpRestrictionTests.cs::StandTpRestrictionTests.CanStandTp::test 0f694e59d32c3c97fbee072d591b74c89561f4648bd3440002d8f54db0058a94 translated
#[test]
fn stand_tp_restriction() {
    assert_eq!(
        check_simple("standTp", RlvPermissionsService::can_stand_tp),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/TempRunRestrictionTests.cs::TempRunRestrictionTests.CanTempRun::test 8893bb24bf10de7e914874c347ac5b73982d33925a1cf29ae8c361c3087be408 translated
#[test]
fn temp_run_restriction() {
    assert_eq!(
        check_simple("tempRun", RlvPermissionsService::can_temp_run),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/TpLmRestrictionTests.cs::TpLmRestrictionTests.CanTpLm::test 847bd3264fd831837d8dab25b235450f19591fef3b3bd0315021727453ad64ee translated
#[test]
fn tp_landmark_restriction() {
    assert_eq!(
        check_simple("tpLm", RlvPermissionsService::can_tp_lm),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/TpLocRestrictionTests.cs::TpLocRestrictionTests.CanTpLoc::test 8e5e2ab1b55b710ecce509b141ccac9bcd9ebbad479868496645ac89574bd089 translated
#[test]
fn tp_location_restriction() {
    assert_eq!(
        check_simple("tpLoc", RlvPermissionsService::can_tp_loc),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/UnsitRestrictionTests.cs::UnsitRestrictionTests.CanUnsit::test 2341a0d230eace08d612a1ae3f9aac7b5a1d3d914f04b6ada4726523e9bd3a37 translated
#[test]
fn unsit_restriction() {
    assert_eq!(
        check_simple("unsit", RlvPermissionsService::can_unsit),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ViewNoteRestrictionTests.cs::ViewNoteRestrictionTests.CanViewNote::test 954472ccc5e060f987260c7d8f87f09dcb252e832c22810ed48dd316a173cf5e translated
#[test]
fn view_note_restriction() {
    assert_eq!(
        check_simple("viewNote", RlvPermissionsService::can_view_note),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ViewScriptRestrictionTests.cs::ViewScriptRestrictionTests.CanViewScript::test 5e9246991c14d80bc83aad4b5944bd9701dc32b354a701a378def8924f7b5315 translated
#[test]
fn view_script_restriction() {
    assert_eq!(
        check_simple("viewScript", RlvPermissionsService::can_view_script),
        [false, true]
    );
}

// parity-case: LibreMetaverse.Tests/RLV/Restrictions/ViewTextureRestrictionTests.cs::ViewTextureRestrictionTests.CanViewTexture::test d1ee89e12ea9c2d971b4d11c82f3129412fd56fa28d2bd2fb923f082eda62571 translated
#[test]
fn view_texture_restriction() {
    assert_eq!(
        check_simple("viewTexture", RlvPermissionsService::can_view_texture),
        [false, true]
    );
}
