//! Exact Rust translations of `DetachAllThisCommandTests`.

use libremetaverse_compat_tests::block_on;
use libremetaverse_compat_tests::rlv_support::{RlvHarness, SampleInventoryTree, guid};
use libremetaverse_rlv::{InventoryMap, RlvAttachmentPoint, RlvWearableType};
use libremetaverse_types::compat::Guid;
const HAPPY: &str = "b1111111-bbbb-4bbb-8bbb-bbbbbbbbbbbb";
const RETRO: &str = "b2222222-bbbb-4bbb-8bbb-bbbbbbbbbbbb";
const GLASSES: &str = "c1111111-cccc-4ccc-8ccc-cccccccccccc";
const FANCY: &str = "d1111111-dddd-4ddd-8ddd-dddddddddddd";
const PRIM1: &str = "11111111-0001-4aaa-8aaa-ffffffffffff";
#[derive(Clone, Copy)]
enum Setup {
    Normal,
    NoStrip,
    NoStripLink,
    Point,
    PointNoStrip,
    PointLink,
    Wearable,
    WearableNoStrip,
    WearableLink,
    WearablePrivate,
}
fn attach(item: &mut libremetaverse_rlv::RlvInventoryItem, point: RlvAttachmentPoint, prim: &str) {
    item.set_attached_to(Some(Some(point)));
    item.set_attached_prim_id(Some(Some(guid(prim))));
}
fn run(command: &str, setup: Setup, sender_item: bool) -> Vec<Guid> {
    let h = RlvHarness::new().expect("RlvService constructor");
    let mut tree = SampleInventoryTree::build().unwrap();
    attach(
        &mut tree.retro_pants,
        RlvAttachmentPoint::Pelvis,
        "11111111-0002-4aaa-8aaa-ffffffffffff",
    );
    attach(
        &mut tree.fancy_hat,
        RlvAttachmentPoint::Chin,
        "11111111-0003-4aaa-8aaa-ffffffffffff",
    );
    if matches!(
        setup,
        Setup::Wearable | Setup::WearableNoStrip | Setup::WearableLink | Setup::WearablePrivate
    ) {
        tree.happy_shirt
            .set_worn_on(Some(Some(RlvWearableType::Pants)));
        tree.glasses.set_worn_on(Some(Some(RlvWearableType::Pants)));
    } else {
        attach(&mut tree.happy_shirt, RlvAttachmentPoint::Chest, PRIM1);
        attach(
            &mut tree.glasses,
            RlvAttachmentPoint::Chest,
            "11111111-0004-4aaa-8aaa-ffffffffffff",
        );
    }
    if matches!(
        setup,
        Setup::NoStrip
            | Setup::NoStripLink
            | Setup::PointNoStrip
            | Setup::PointLink
            | Setup::WearableNoStrip
            | Setup::WearableLink
    ) {
        tree.hats.set_name("nostrip Hats".into());
        tree.retro_pants.set_name("nostrip Retro Pants".into());
    }
    if matches!(
        setup,
        Setup::NoStripLink | Setup::PointLink | Setup::WearableLink
    ) {
        tree.fancy_hat.set_is_link(true);
        attach(
            &mut tree.party_hat,
            RlvAttachmentPoint::Chin,
            "11111111-0005-4aaa-8aaa-ffffffffffff",
        );
    }
    if matches!(setup, Setup::WearablePrivate) {
        tree.hats.set_name(".hats".into());
    }
    h.queries.lock().unwrap().inventory_map = Some(InventoryMap::new(tree.root, vec![]).unwrap());
    if sender_item {
        block_on(h.process_from(command, PRIM1, "Happy Shirt")).unwrap();
    } else {
        block_on(h.process(command)).unwrap();
    }
    let mut v = h.actions.lock().unwrap().detachments[0].clone();
    v.sort_by_key(|id| id.0);
    v
}
fn ids(values: &[&str]) -> Vec<Guid> {
    let mut v: Vec<_> = values.iter().map(|s| guid(s)).collect();
    v.sort_by_key(|id| id.0);
    v
}
fn normal() -> Vec<Guid> {
    ids(&[HAPPY, RETRO, FANCY])
}
fn nostrip() -> Vec<Guid> {
    ids(&[HAPPY])
}
fn link() -> Vec<Guid> {
    ids(&[HAPPY, FANCY])
}
fn selected() -> Vec<Guid> {
    ids(&[HAPPY, RETRO, GLASSES, FANCY])
}
fn selected_nostrip() -> Vec<Guid> {
    ids(&[HAPPY, GLASSES])
}
fn selected_link() -> Vec<Guid> {
    ids(&[HAPPY, GLASSES, FANCY])
}

// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_Default::test 8fe4eacf8cc5841e638d69540e2ab080efc3e64534346ece854429d0476f8a84 translated
#[test]
fn detach_all_this_default() {
    assert_eq!(run("@detachallthis=force", Setup::Normal, true), normal());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_Nostrip::test 754bd01f2f0b77c05ee5d1548f76337da93d980a48ad0922d80f34707c4fe68b translated
#[test]
fn detach_all_this_honors_nostrip() {
    assert_eq!(run("@detachallthis=force", Setup::NoStrip, true), nostrip());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_Nostrip_LinkException::test 0cce15f7cfda160733c305b0867be31875e1814b38e2e980525d960e0214ad51 translated
#[test]
fn detach_all_this_honors_link_exception() {
    assert_eq!(
        run("@detachallthis=force", Setup::NoStripLink, true),
        link()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_ById::test 2f657ffed317d4d7f97f6111942ea8214996872da6294f7c66d07890647f7f63 translated
#[test]
fn detach_all_this_by_id() {
    assert_eq!(
        run(
            &format!("@detachallthis:{PRIM1}=force"),
            Setup::Normal,
            false
        ),
        normal()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_ById_Nostrip::test 48ab7aec02efd652478ca3110dd39011fd9b79a1e0a1336f53e9f77b2f56e635 translated
#[test]
fn detach_all_this_by_id_honors_nostrip() {
    assert_eq!(
        run(
            &format!("@detachallthis:{PRIM1}=force"),
            Setup::NoStrip,
            false
        ),
        nostrip()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_ById_Nostrip_LinkException::test 5d882f00bfe73cecfc3e96c26ff18a20c00481619996b25ed2ce851eff9a86ce translated
#[test]
fn detach_all_this_by_id_honors_link_exception() {
    assert_eq!(
        run(
            &format!("@detachallthis:{PRIM1}=force"),
            Setup::NoStripLink,
            false
        ),
        link()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachThisAllForce_ByRlvAttachmentPoint::test 30e6806d5c484bf2a2f9a3b1fcdb5e88272874b0e755462c3b0bfa97326d180c translated
#[test]
fn detach_all_this_by_attachment_point() {
    assert_eq!(
        run("@detachallthis:chest=force", Setup::Point, false),
        selected()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachThisAllForce_ByRlvAttachmentPoint_NoStrip::test 657125be7aec668f72e744cc87cae38f022c8ccf9e8980c8ef4bea7e0557fdd1 translated
#[test]
fn detach_all_this_by_attachment_point_honors_nostrip() {
    assert_eq!(
        run("@detachallthis:chest=force", Setup::PointNoStrip, false),
        selected_nostrip()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachThisAllForce_ByRlvAttachmentPoint_NoStrip_LinkException::test fe019191a9a3df9a43fd500db775ba5f874f4b767096365cba390480b2b2189f translated
#[test]
fn detach_all_this_by_attachment_point_honors_link_exception() {
    assert_eq!(
        run("@detachallthis:chest=force", Setup::PointLink, false),
        selected_link()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_ByRlvWearableType::test ccf302d870f323790af63873fcbb172f084c4e7400a728e480378706b5fb9947 translated
#[test]
fn detach_all_this_by_wearable() {
    assert_eq!(
        run("@detachallthis:pants=force", Setup::Wearable, false),
        selected()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_ByRlvWearableType_NoStrip::test 1947e7c9cfe8bb931ee7ad50c6f505515feeb9d30b236702a2d68fb4734a30f0 translated
#[test]
fn detach_all_this_by_wearable_honors_nostrip() {
    assert_eq!(
        run("@detachallthis:pants=force", Setup::WearableNoStrip, false),
        selected_nostrip()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_ByRlvWearableType_NoStrip_LinkException::test 50ec101ab557e78d947ac7f9878acd4df4957482f358a7ce02371df8754add94 translated
#[test]
fn detach_all_this_by_wearable_honors_link_exception() {
    assert_eq!(
        run("@detachallthis:pants=force", Setup::WearableLink, false),
        selected_link()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllThisCommandTests.cs::DetachAllThisCommandTests.DetachAllThisForce_ByRlvWearableType_PrivateFolder::test 2ba745b093f0348d8754f74073c6a6a0f18383b5ce4a73721b39b01f0306a994 translated
#[test]
fn detach_all_this_by_wearable_skips_private_folder() {
    assert_eq!(
        run("@detachallthis:pants=force", Setup::WearablePrivate, false),
        ids(&[HAPPY, RETRO, GLASSES])
    );
}
