// This file contains WASM-only tests for session manager logic in the vault crate.
// All code is strictly separated from native using cfg attributes.
#![cfg(target_arch = "wasm32")]
//! WASM test for session manager logic in the vault crate.

use wasm_bindgen_test::*;
use vault::session::SessionManager;
use vault::Vault;


wasm_bindgen_test_configure!(run_in_browser);

#[wasm_bindgen_test(async)]
async fn test_session_manager_lock_unlock_keypairs_persistence() {
    use kvstore::wasm::WasmStore;
    use vault::{Vault, KeyType, KeyMetadata};
    use vault::session::SessionManager;
    let store = WasmStore::open("test-session-manager-lock-unlock").await.unwrap();
    let mut vault = Vault::new(store);
    let keyspace = "testspace2";
    let password = b"testpass2";

    // 1. Create session manager
    let mut session = SessionManager::new(vault);
    // Create and unlock keyspace in one step
    session.create_keyspace(keyspace, password, None).await.expect("create_keyspace via session");
    // 2. Add two keypairs with names using session API
    let meta1 = KeyMetadata { name: Some("keypair-one".to_string()), created_at: None, tags: None };
    let meta2 = KeyMetadata { name: Some("keypair-two".to_string()), created_at: None, tags: None };
    let id1 = session.add_keypair(Some(KeyType::Secp256k1), Some(meta1.clone())).await.expect("add_keypair1 via session");
    let id2 = session.add_keypair(Some(KeyType::Ed25519), Some(meta2.clone())).await.expect("add_keypair2 via session");

    // 3. List, store keys and names
    let keypairs_before = session.list_keypairs().expect("list_keypairs before").iter().map(|k| (k.id.clone(), k.public_key.clone(), k.private_key.clone(), k.metadata.clone())).collect::<Vec<_>>();
    let keypairs_before = session.list_keypairs().expect("list_keypairs before").iter().map(|k| (k.id.clone(), k.public_key.clone(), k.private_key.clone(), k.metadata.clone())).collect::<Vec<_>>();
    assert_eq!(keypairs_before.len(), 2);
    assert!(keypairs_before.iter().any(|k| k.0 == id1 && k.3.as_ref().unwrap().name.as_deref() == Some("keypair-one")));
    assert!(keypairs_before.iter().any(|k| k.0 == id2 && k.3.as_ref().unwrap().name.as_deref() == Some("keypair-two")));

    // 4. Lock (logout)
    session.logout();
    assert!(session.current_keyspace().is_none());

    // 5. Unlock again
    session.unlock_keyspace(keyspace, password).await.expect("unlock_keyspace again");
    // select_keyspace removed; unlocking a keyspace is sufficient after refactor.

    // 6. List and check keys/names match
    let keypairs_after = session.list_keypairs().expect("list_keypairs after").iter().map(|k| (k.id.clone(), k.public_key.clone(), k.private_key.clone(), k.metadata.clone())).collect::<Vec<_>>();
    assert_eq!(keypairs_before, keypairs_after, "Keypairs before and after lock/unlock should match");
}

#[wasm_bindgen_test(async)]
async fn test_session_manager_end_to_end() {
    use kvstore::wasm::WasmStore;
    use vault::{Vault, KeyType, KeyMetadata};
    use vault::session::SessionManager;
    let store = WasmStore::open("test-session-manager").await.unwrap();
    let keyspace = "testspace";
    let password = b"testpass";

    // Create session manager
    let mut session = SessionManager::new(Vault::new(store));
    // Create and unlock keyspace in one step
    session.create_keyspace(keyspace, password, None).await.expect("create_keyspace via session");
    // Add keypair using session API
    let key_id = session.add_keypair(Some(KeyType::Secp256k1), Some(KeyMetadata { name: Some("main".to_string()), created_at: None, tags: None })).await.expect("add_keypair via session");

    // Test add_keypair with metadata via SessionManager
    let meta = KeyMetadata { name: Some("user1-key".to_string()), created_at: None, tags: Some(vec!["tag1".to_string()]) };
    let key_id2 = session.add_keypair(Some(KeyType::Ed25519), Some(meta.clone())).await.expect("add_keypair via session");
    // List keypairs and check metadata
    let keypairs = session.list_keypairs().expect("list_keypairs");
    assert!(keypairs.iter().any(|k| k.id == key_id2 && k.metadata.as_ref().unwrap().name.as_deref() == Some("user1-key")), "metadata name should be present");
}
