//! Exact Rust translations of `DetachAllCommandTests`.

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 RETRO: &str = "b2222222-bbbb-4bbb-8bbb-bbbbbbbbbbbb";
const HAPPY: &str = "b1111111-bbbb-4bbb-8bbb-bbbbbbbbbbbb";
const FANCY: &str = "d1111111-dddd-4ddd-8ddd-dddddddddddd";
#[derive(Clone, Copy)]
enum Setup {
    Default,
    Restricted,
    PrivateTarget,
    PrivateSubfolder,
    NoStripFolder,
    NoStripLink,
    NoStripItem,
}

fn run(setup: Setup) -> Vec<Guid> {
    let h = RlvHarness::new().expect("RlvService constructor");
    let mut tree = SampleInventoryTree::build().unwrap();
    tree.retro_pants
        .set_attached_to(Some(Some(RlvAttachmentPoint::Pelvis)));
    tree.retro_pants
        .set_attached_prim_id(Some(Some(guid("11111111-0002-4aaa-8aaa-ffffffffffff"))));
    tree.glasses.set_worn_on(Some(Some(RlvWearableType::Pants)));
    tree.happy_shirt
        .set_worn_on(Some(Some(RlvWearableType::Pants)));
    if !matches!(setup, Setup::NoStripItem) {
        tree.fancy_hat
            .set_attached_to(Some(Some(RlvAttachmentPoint::Chin)));
        tree.fancy_hat
            .set_attached_prim_id(Some(Some(guid("11111111-0003-4aaa-8aaa-ffffffffffff"))));
    }
    match setup {
        Setup::PrivateTarget => tree.clothing.set_name(".clothing".into()),
        Setup::PrivateSubfolder => {
            tree.clothing.set_name(".clothing".into());
            tree.hats.set_name(".hats".into());
        }
        Setup::NoStripFolder | Setup::NoStripLink => {
            tree.clothing.set_name(".clothing".into());
            tree.hats.set_name("nostrip hats".into());
        }
        Setup::NoStripItem => tree.happy_shirt.set_name("nostrip Happy Shirt".into()),
        _ => {}
    }
    if matches!(setup, Setup::NoStripLink) {
        tree.party_hat
            .set_attached_to(Some(Some(RlvAttachmentPoint::Chin)));
        tree.party_hat
            .set_attached_prim_id(Some(Some(guid("11111111-0004-4aaa-8aaa-ffffffffffff"))));
        tree.fancy_hat.set_is_link(true);
    }
    h.queries.lock().unwrap().inventory_map = Some(InventoryMap::new(tree.root, vec![]).unwrap());
    if matches!(setup, Setup::Restricted) {
        block_on(h.process("@detachthis:Clothing=n")).unwrap();
    }
    let path = if matches!(
        setup,
        Setup::PrivateTarget | Setup::PrivateSubfolder | Setup::NoStripFolder | Setup::NoStripLink
    ) {
        ".clothing"
    } else {
        "Clothing"
    };
    block_on(h.process(&format!("@detachall:{path}=force"))).unwrap();
    let mut result = h.actions.lock().unwrap().detachments[0].clone();
    result.sort_by_key(|id| id.0);
    result
}
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/DetachAllCommandTests.cs::DetachAllCommandTests.DetachAllForce_Recursive::test 45405dbca6c2b8bb9f439736d53c2ff60056252f4cdf6296bedcc14d2be9248e translated
#[test]
fn detach_all_recursive() {
    assert_eq!(run(Setup::Default), ids(&[FANCY, HAPPY, RETRO]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllCommandTests.cs::DetachAllCommandTests.DetachAllForce_Recursive_EnforceRestrictions::test 6186f5923009fb984daef726e8df44aff7cb65f74c2e381dd8cc9968f5534e43 translated
#[test]
fn detach_all_enforces_restrictions() {
    assert_eq!(run(Setup::Restricted), ids(&[FANCY]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllCommandTests.cs::DetachAllCommandTests.DetachAllForce_Recursive_PrivateTargetDir::test 300a323967b6258d1202190bbd3de7b91699231f7a5afa86204ba627cb61215f translated
#[test]
fn detach_all_private_target() {
    assert_eq!(run(Setup::PrivateTarget), ids(&[FANCY, HAPPY, RETRO]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllCommandTests.cs::DetachAllCommandTests.DetachAllForce_Recursive_PrivateSubFolders::test e688b64d13f0a07f4bfeae0715fbfbf98c1d1fa64b0aefbd0e4e3d3d4dd98eee translated
#[test]
fn detach_all_skips_private_subfolders() {
    assert_eq!(run(Setup::PrivateSubfolder), ids(&[HAPPY, RETRO]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllCommandTests.cs::DetachAllCommandTests.DetachAllForce_Recursive_NostripSubFolders::test 22cf1a159861c98c8a0f14ac63bafcbef21466c2ac01e615fe9ca4630d16f956 translated
#[test]
fn detach_all_honors_nostrip_subfolders() {
    assert_eq!(run(Setup::NoStripFolder), ids(&[HAPPY, RETRO]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllCommandTests.cs::DetachAllCommandTests.DetachAllForce_Recursive_NostripSubFolders_LinkException::test cbe38368a6d4c59d72291195688d0c70898be5c3cceb02f09c5d386c3668fb07 translated
#[test]
fn detach_all_honors_link_exception() {
    assert_eq!(run(Setup::NoStripLink), ids(&[HAPPY, RETRO, FANCY]));
}
// parity-case: LibreMetaverse.Tests/RLV/Commands/DetachAllCommandTests.cs::DetachAllCommandTests.DetachAllForce_Recursive_NostripItemName::test ea0fab47cb1829338948f605919fcf1dca4f88d7965cdca4c7f457e399e4fbfc translated
#[test]
fn detach_all_honors_nostrip_item() {
    assert_eq!(run(Setup::NoStripItem), ids(&[RETRO]));
}
