//! Exact Rust translations of every `detach`/`remattach` alias case.

use libremetaverse_compat_tests::block_on;
use libremetaverse_compat_tests::rlv_support::{RlvHarness, SampleInventoryTree, guid};
use libremetaverse_rlv::{InventoryMap, RlvAttachmentPoint, RlvInventoryItem, RlvWearableType};
use libremetaverse_types::compat::Guid;
const HAPPY: &str = "b1111111-bbbb-4bbb-8bbb-bbbbbbbbbbbb";
const RETRO: &str = "b2222222-bbbb-4bbb-8bbb-bbbbbbbbbbbb";
const FANCY: &str = "d1111111-dddd-4ddd-8ddd-dddddddddddd";
const EXTERNAL: &str = "12312312-0002-4aaa-8aaa-aaaaaaaaaaaa";
const PRIM1: &str = "11111111-0001-4aaa-8aaa-ffffffffffff";
const EXTERNAL_PRIM: &str = "12312312-0002-4aaa-8aaa-ffffffffffff";
#[derive(Clone, Copy)]
enum Setup {
    Normal,
    NoStrip,
    NoStripLink,
    External,
    Folder,
    FolderNoStrip,
    FolderLink,
    Point,
    PointNoStrip,
    PointLink,
    PointNone,
    Uuid,
    UuidItemNoStrip,
    UuidFolderNoStrip,
    UuidFolderLink,
    UuidRestricted,
    UuidExternal,
}
fn attach(item: &mut RlvInventoryItem, point: RlvAttachmentPoint, prim: &str) {
    item.set_attached_to(Some(Some(point)));
    item.set_attached_prim_id(Some(Some(guid(prim))));
}
fn external(
    id: &str,
    name: &str,
    point: Option<RlvAttachmentPoint>,
    prim: Option<&str>,
    worn: Option<RlvWearableType>,
) -> RlvInventoryItem {
    RlvInventoryItem::new(
        guid(id),
        name.into(),
        false,
        Some(Some(guid("12312312-aaaa-4aaa-8aaa-aaaaaaaaaaaa"))),
        point.map(Some),
        prim.map(|v| Some(guid(v))),
        worn.map(Some),
        None,
    )
    .unwrap()
}
fn base(tree: &mut SampleInventoryTree) {
    attach(&mut tree.happy_shirt, RlvAttachmentPoint::Chest, PRIM1);
    attach(
        &mut tree.fancy_hat,
        RlvAttachmentPoint::Chin,
        "11111111-0003-4aaa-8aaa-ffffffffffff",
    );
    tree.retro_pants
        .set_worn_on(Some(Some(RlvWearableType::Pants)));
}
#[allow(clippy::too_many_lines)]
fn run(command: &str, setup: Setup) -> Vec<Guid> {
    let h = RlvHarness::new().expect("RlvService constructor");
    let mut tree = SampleInventoryTree::build().unwrap();
    let mut external_items = vec![];
    base(&mut tree);
    match setup {
        Setup::NoStrip | Setup::NoStripLink => {
            tree.hats.set_name("nostrip Hats".into());
            tree.happy_shirt.set_name("nostrip Happy Shirt".into());
            attach(
                &mut tree.retro_pants,
                RlvAttachmentPoint::Groin,
                "11111111-0005-4aaa-8aaa-ffffffffffff",
            );
            if matches!(setup, Setup::NoStripLink) {
                tree.fancy_hat.set_is_link(true);
            }
        }
        Setup::External => {
            external_items.push(external(
                "12312312-0001-4aaa-8aaa-aaaaaaaaaaaa",
                "External Tattoo",
                None,
                None,
                Some(RlvWearableType::Tattoo),
            ));
            external_items.push(external(
                EXTERNAL,
                "External Jaw Thing",
                Some(RlvAttachmentPoint::Jaw),
                Some(EXTERNAL_PRIM),
                None,
            ));
        }
        Setup::FolderNoStrip | Setup::FolderLink => {
            tree.hats.set_name("nostrip Hats".into());
            if matches!(setup, Setup::FolderLink) {
                tree.fancy_hat.set_is_link(true);
            }
        }
        Setup::Point => external_items.push(external(
            EXTERNAL,
            "External Chest Thing",
            Some(RlvAttachmentPoint::Chest),
            Some(EXTERNAL_PRIM),
            None,
        )),
        Setup::PointNoStrip | Setup::PointLink => {
            tree.hats.set_name("nostrip Hats".into());
            tree.happy_shirt.set_name("nostrip Happy Shirt".into());
            attach(
                &mut tree.fancy_hat,
                RlvAttachmentPoint::Chest,
                "11111111-0003-4aaa-8aaa-ffffffffffff",
            );
            attach(
                &mut tree.retro_pants,
                RlvAttachmentPoint::Chest,
                "11111111-0005-4aaa-8aaa-ffffffffffff",
            );
            if matches!(setup, Setup::PointLink) {
                tree.fancy_hat.set_is_link(true);
            }
            external_items.push(external(
                EXTERNAL,
                "External Chest Thing",
                Some(RlvAttachmentPoint::Chest),
                Some(EXTERNAL_PRIM),
                None,
            ));
            external_items.push(external(
                "12312312-0003-4aaa-8aaa-aaaaaaaaaaaa",
                "nostrip External Chest Thing",
                Some(RlvAttachmentPoint::Chest),
                Some("12312312-0003-4aaa-8aaa-ffffffffffff"),
                None,
            ));
        }
        Setup::UuidItemNoStrip => tree.happy_shirt.set_name("nostrip Happy Shirt".into()),
        Setup::UuidFolderNoStrip | Setup::UuidFolderLink => {
            tree.clothing.set_name("nostrip Clothing".into());
            if matches!(setup, Setup::UuidFolderLink) {
                tree.happy_shirt.set_is_link(true);
            }
        }
        Setup::UuidExternal => external_items.push(external(
            EXTERNAL,
            "External Jaw Thing",
            Some(RlvAttachmentPoint::Jaw),
            Some(EXTERNAL_PRIM),
            None,
        )),
        _ => {}
    }
    h.queries.lock().unwrap().inventory_map =
        Some(InventoryMap::new(tree.root, external_items).unwrap());
    if matches!(setup, Setup::UuidRestricted) {
        block_on(h.process("@detachallthis:Clothing=n")).unwrap();
    }
    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
}

// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach::case:bb1d34dc76ade75f 16420d56c60229e8d8b6a2a0d63b1f500112c23cef451d69bb0ed97fe9b63bae translated
#[test]
fn detach_all_attachments() {
    assert_eq!(run("@detach=force", Setup::Normal), ids(&[HAPPY, FANCY]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach::case:c9faa5be8fef55e8 16420d56c60229e8d8b6a2a0d63b1f500112c23cef451d69bb0ed97fe9b63bae translated
#[test]
fn remattach_all_attachments() {
    assert_eq!(run("@remattach=force", Setup::Normal), ids(&[HAPPY, FANCY]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_NoStrip::case:bb1d34dc76ade75f 5b3f1cbe99833e16c6f10ef568618627445babbcdfc9be555b48257bfdffeea7 translated
#[test]
fn detach_honors_nostrip() {
    assert_eq!(run("@detach=force", Setup::NoStrip), ids(&[RETRO]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_NoStrip::case:c9faa5be8fef55e8 5b3f1cbe99833e16c6f10ef568618627445babbcdfc9be555b48257bfdffeea7 translated
#[test]
fn remattach_honors_nostrip() {
    assert_eq!(run("@remattach=force", Setup::NoStrip), ids(&[RETRO]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_NoStrip_LinkException::case:bb1d34dc76ade75f 96a4b53d9e55dcd656c25af6619a3d0d67f5bc2517a759d722559a4ffb225472 translated
#[test]
fn detach_honors_nostrip_link_exception() {
    assert_eq!(
        run("@detach=force", Setup::NoStripLink),
        ids(&[RETRO, FANCY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_NoStrip_LinkException::case:c9faa5be8fef55e8 96a4b53d9e55dcd656c25af6619a3d0d67f5bc2517a759d722559a4ffb225472 translated
#[test]
fn remattach_honors_nostrip_link_exception() {
    assert_eq!(
        run("@remattach=force", Setup::NoStripLink),
        ids(&[RETRO, FANCY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ExternalItems::case:bb1d34dc76ade75f 7545f36532fcb7974a9e009e567b2342754a11da95eb3f17ee04089dcec42664 translated
#[test]
fn detach_external_items() {
    assert_eq!(
        run("@detach=force", Setup::External),
        ids(&[HAPPY, FANCY, EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ExternalItems::case:c9faa5be8fef55e8 7545f36532fcb7974a9e009e567b2342754a11da95eb3f17ee04089dcec42664 translated
#[test]
fn remattach_external_items() {
    assert_eq!(
        run("@remattach=force", Setup::External),
        ids(&[HAPPY, FANCY, EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByFolder::case:97eb7af1f9c3c62c 583d3f596c80411d950038e3ec64032bee75150b8c819741fe89a4ca40eb2553 translated
#[test]
fn detach_by_folder() {
    assert_eq!(
        run("@detach:Clothing/Hats=force", Setup::Folder),
        ids(&[FANCY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByFolder::case:1a04fd408fddaac0 583d3f596c80411d950038e3ec64032bee75150b8c819741fe89a4ca40eb2553 translated
#[test]
fn remattach_by_folder() {
    assert_eq!(
        run("@remattach:Clothing/Hats=force", Setup::Folder),
        ids(&[FANCY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByFolder_NoStrip::case:2117c838922f5ba4 3a21b8ae807126d6f93ac95e16c47330b4146ace9781e9c9665ad493ee8c48b1 translated
#[test]
fn detach_by_folder_honors_nostrip() {
    assert!(run("@detach:Clothing/nostrip Hats=force", Setup::FolderNoStrip).is_empty());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByFolder_NoStrip::case:11d4ca4fd3e35db1 3a21b8ae807126d6f93ac95e16c47330b4146ace9781e9c9665ad493ee8c48b1 translated
#[test]
fn remattach_by_folder_honors_nostrip() {
    assert!(
        run(
            "@remattach:Clothing/nostrip Hats=force",
            Setup::FolderNoStrip
        )
        .is_empty()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByFolder_NoStrip_LinkException::case:2117c838922f5ba4 7c00e7dc70b3078d75009cf78a9fece889eee85f237c1a3c79c6249ae5e5327f translated
#[test]
fn detach_by_folder_honors_link_exception() {
    assert_eq!(
        run("@detach:Clothing/nostrip Hats=force", Setup::FolderLink),
        ids(&[FANCY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByFolder_NoStrip_LinkException::case:11d4ca4fd3e35db1 7c00e7dc70b3078d75009cf78a9fece889eee85f237c1a3c79c6249ae5e5327f translated
#[test]
fn remattach_by_folder_honors_link_exception() {
    assert_eq!(
        run("@remattach:Clothing/nostrip Hats=force", Setup::FolderLink),
        ids(&[FANCY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByAttachmentPoint::case:644d3f75f3570ac3 e09627228c1cf8311e56ac6660389bc1b268db8fd4f883dc40aaf3d2ec00916b translated
#[test]
fn detach_by_attachment_point() {
    assert_eq!(
        run("@detach:chest=force", Setup::Point),
        ids(&[HAPPY, EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByAttachmentPoint::case:53be219b37533fa6 e09627228c1cf8311e56ac6660389bc1b268db8fd4f883dc40aaf3d2ec00916b translated
#[test]
fn remattach_by_attachment_point() {
    assert_eq!(
        run("@remattach:chest=force", Setup::Point),
        ids(&[HAPPY, EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByAttachmentPoint_NoStrip::case:644d3f75f3570ac3 ffaaad92700d5d606154abdddd05c24c7584c5c3e55290df61e2b2a71d8148d7 translated
#[test]
fn detach_by_attachment_point_honors_nostrip() {
    assert_eq!(
        run("@detach:chest=force", Setup::PointNoStrip),
        ids(&[RETRO, EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByAttachmentPoint_NoStrip::case:53be219b37533fa6 ffaaad92700d5d606154abdddd05c24c7584c5c3e55290df61e2b2a71d8148d7 translated
#[test]
fn remattach_by_attachment_point_honors_nostrip() {
    assert_eq!(
        run("@remattach:chest=force", Setup::PointNoStrip),
        ids(&[RETRO, EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByAttachmentPoint_NoStrip_LinkException::case:644d3f75f3570ac3 af1b1caf070a186bc2b02b598919b52d47c289d708fde3713e48ce1a40d7c025 translated
#[test]
fn detach_by_attachment_point_honors_link_exception() {
    assert_eq!(
        run("@detach:chest=force", Setup::PointLink),
        ids(&[RETRO, FANCY, EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByAttachmentPoint_NoStrip_LinkException::case:53be219b37533fa6 af1b1caf070a186bc2b02b598919b52d47c289d708fde3713e48ce1a40d7c025 translated
#[test]
fn remattach_by_attachment_point_honors_link_exception() {
    assert_eq!(
        run("@remattach:chest=force", Setup::PointLink),
        ids(&[RETRO, FANCY, EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByAttachmentPoint_None::case:9a124e69f33b279f afed603254ad6048a46e157254f16253063e6c76c9ea16f46a69d8455bc0e6fb translated
#[test]
fn detach_by_missing_attachment_point() {
    assert!(run("@detach:skull=force", Setup::PointNone).is_empty());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByAttachmentPoint_None::case:800d7d8ba57071b1 afed603254ad6048a46e157254f16253063e6c76c9ea16f46a69d8455bc0e6fb translated
#[test]
fn remattach_by_missing_attachment_point() {
    assert!(run("@remattach:skull=force", Setup::PointNone).is_empty());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID::case:e5bdbdba9613b46a 4b1a8acea7f1bb100bf11e9329672c64b53aba4974558f1c693460eef7f56c2d translated
#[test]
fn detach_by_uuid() {
    assert_eq!(
        run(&format!("@detach:{PRIM1}=force"), Setup::Uuid),
        ids(&[HAPPY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID::case:7cb3f81460bd8e9f 4b1a8acea7f1bb100bf11e9329672c64b53aba4974558f1c693460eef7f56c2d translated
#[test]
fn remattach_by_uuid() {
    assert_eq!(
        run(&format!("@remattach:{PRIM1}=force"), Setup::Uuid),
        ids(&[HAPPY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_NostripInItemName::case:e5bdbdba9613b46a 6857733912b45ef9153b0f58cd74ae6c9dc0034fa10933d153cae88a2c7d9423 translated
#[test]
fn detach_by_uuid_honors_item_nostrip() {
    assert!(run(&format!("@detach:{PRIM1}=force"), Setup::UuidItemNoStrip).is_empty());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_NostripInItemName::case:7cb3f81460bd8e9f 6857733912b45ef9153b0f58cd74ae6c9dc0034fa10933d153cae88a2c7d9423 translated
#[test]
fn remattach_by_uuid_honors_item_nostrip() {
    assert!(run(&format!("@remattach:{PRIM1}=force"), Setup::UuidItemNoStrip).is_empty());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_NostripInFolderName::case:e5bdbdba9613b46a 1a3189f931e086ab3d2d3e99c53dba2e9d39dce75a52fd02400c6892aef5d0c4 translated
#[test]
fn detach_by_uuid_honors_folder_nostrip() {
    assert!(run(&format!("@detach:{PRIM1}=force"), Setup::UuidFolderNoStrip).is_empty());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_NostripInFolderName::case:7cb3f81460bd8e9f 1a3189f931e086ab3d2d3e99c53dba2e9d39dce75a52fd02400c6892aef5d0c4 translated
#[test]
fn remattach_by_uuid_honors_folder_nostrip() {
    assert!(
        run(
            &format!("@remattach:{PRIM1}=force"),
            Setup::UuidFolderNoStrip
        )
        .is_empty()
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_NostripInFolderName_LinkException::case:e5bdbdba9613b46a bd7bc72a107b4a21b00977e13b086da192bef2c2e6f0fdb73b8e332016c6ef23 translated
#[test]
fn detach_by_uuid_honors_folder_link_exception() {
    assert_eq!(
        run(&format!("@detach:{PRIM1}=force"), Setup::UuidFolderLink),
        ids(&[HAPPY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_NostripInFolderName_LinkException::case:7cb3f81460bd8e9f bd7bc72a107b4a21b00977e13b086da192bef2c2e6f0fdb73b8e332016c6ef23 translated
#[test]
fn remattach_by_uuid_honors_folder_link_exception() {
    assert_eq!(
        run(&format!("@remattach:{PRIM1}=force"), Setup::UuidFolderLink),
        ids(&[HAPPY])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_WithRestrictions::case:e5bdbdba9613b46a 2ecf40d1d338117ddac4cfd6c7a030e96b7adf72cd90e0d8327787317e1f38d7 translated
#[test]
fn detach_by_uuid_honors_restrictions() {
    assert!(run(&format!("@detach:{PRIM1}=force"), Setup::UuidRestricted).is_empty());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_WithRestrictions::case:7cb3f81460bd8e9f 2ecf40d1d338117ddac4cfd6c7a030e96b7adf72cd90e0d8327787317e1f38d7 translated
#[test]
fn remattach_by_uuid_honors_restrictions() {
    assert!(run(&format!("@remattach:{PRIM1}=force"), Setup::UuidRestricted).is_empty());
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_External::case:e5bdbdba9613b46a e0bdc682df3416bdc01855e6e63974e64c21951aac629807352220baf572dded translated
#[test]
fn detach_external_by_uuid() {
    assert_eq!(
        run(
            &format!("@detach:{EXTERNAL_PRIM}=force"),
            Setup::UuidExternal
        ),
        ids(&[EXTERNAL])
    );
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/RemAttachCommandTests.cs::RemAttachCommandTests.RemAttach_ByUUID_External::case:7cb3f81460bd8e9f e0bdc682df3416bdc01855e6e63974e64c21951aac629807352220baf572dded translated
#[test]
fn remattach_external_by_uuid() {
    assert_eq!(
        run(
            &format!("@remattach:{EXTERNAL_PRIM}=force"),
            Setup::UuidExternal
        ),
        ids(&[EXTERNAL])
    );
}
