// Exact Rust translations of LibreMetaverse.Tests/ConstructorNullArgumentTests.cs and
// LibreMetaverse.Tests/InventoryManagerTests.cs inventory-owned cases.
// Source SHA-256: 28deea0bf4d9353a2424842c6184abab8fe82746ceb12e093912728a247f21bc
// Source SHA-256: 9fd33d6a4e9f3aa2d414439203eecda605ede3eb6e848533ef0778b023407c3d

use libremetaverse::{
    Error, InventoryItem, InventoryManager, InventoryNotecard, InventoryTexture, Permissions,
};
use libremetaverse_types::{AssetType, InventoryType, SaleType, UUID};
use std::time::SystemTime;

fn uuid() -> UUID {
    UUID::random().expect("UUID Random")
}

// parity-case: LibreMetaverse.Tests/ConstructorNullArgumentTests.cs::ConstructorNullArgumentTests.InventoryManager_Null_Throws::test 5e7498066c944800354abbc71eea825fe90d0c40a25a6065967a3ebcc9efea74 translated
#[test]
fn inventory_manager_null_throws() {
    match InventoryManager::new(None) {
        Err(error) => assert_eq!(error, Error::ArgumentNull),
        Ok(_) => panic!("expected ArgumentNull for client"),
    }
}

// parity-case: LibreMetaverse.Tests/InventoryManagerTests.cs::InventoryManagerTests.EncryptDecrypt_RoundTrip::test 7b59c330ffacf1174dd884f369a4e4015e1a212a0e43d7fa8889f7505dd5599d translated
#[test]
fn encrypt_decrypt_round_trip() {
    let asset_id = uuid();
    let shadow = InventoryManager::encrypt_asset_id(asset_id).expect("EncryptAssetID");
    let decrypted = InventoryManager::decrypt_shadow_id(shadow).expect("DecryptShadowID");
    assert_eq!(decrypted, asset_id);
}

// parity-case: LibreMetaverse.Tests/InventoryManagerTests.cs::InventoryManagerTests.ItemCRC_IsDeterministic_AndChangesWhenFieldsChange::test dbd322778ad7f110abce5f10a0c83ad002ae76f6a114fa795fb90a799f4ff077 translated
#[test]
fn item_crc_is_deterministic_and_changes_when_fields_change() {
    let mut item = InventoryItem::new_with_uuid(uuid()).expect("InventoryItem constructor");
    item.set_asset_uuid(uuid());
    item.base.set_parent_uuid(uuid());
    item.set_creator_id(uuid());
    item.base.set_owner_id(uuid());
    item.set_group_id(uuid());
    item.set_flags(0x1234_5678);
    item.set_inventory_type(InventoryType::OBJECT);
    item.set_asset_type(AssetType::Object);
    item.set_creation_date(SystemTime::now());
    item.set_sale_price(42);
    item.set_sale_type(SaleType::Not);
    item.set_permissions(Permissions::full_permissions());

    let crc1 = InventoryManager::item_crc(&item).expect("ItemCRC first");
    let crc2 = InventoryManager::item_crc(&item).expect("ItemCRC second");
    assert_eq!(crc2, crc1, "ItemCRC must be deterministic");

    item.set_asset_uuid(uuid());
    let crc3 = InventoryManager::item_crc(&item).expect("ItemCRC changed");
    assert_ne!(crc3, crc1, "ItemCRC must include AssetUUID");
}

// parity-case: LibreMetaverse.Tests/InventoryManagerTests.cs::InventoryManagerTests.CreateInventoryItem_ReturnsCorrectSubclass::test 219f8c91bc1b3d5b5d3e5b2f2880c5733fd02e6103ccc9c6ecbf8d03328274f6 translated
#[test]
fn create_inventory_item_returns_correct_subclass() {
    let id = uuid();
    let texture = InventoryManager::create_inventory_item(InventoryType::TEXTURE, id)
        .expect("CreateInventoryItem texture");
    let notecard = InventoryManager::create_inventory_item(InventoryType::NOTECARD, id)
        .expect("CreateInventoryItem notecard");
    // C# explicitly casts 999 to the signed-byte-backed InventoryType, yielding -25.
    let unknown = InventoryManager::create_inventory_item(InventoryType(-25), id)
        .expect("CreateInventoryItem unknown");

    assert!(texture.as_any().is::<InventoryTexture>());
    assert!(notecard.as_any().is::<InventoryNotecard>());
    assert!(unknown.as_any().is::<InventoryItem>());
}
