//! Integration tests for the VaultService lifecycle.
//!
//! These tests verify the unlock/lock lifecycle, error conditions,
//! and that the vault correctly manages state transitions.

use alknet_vault::derivation::PATHS;
use alknet_vault::service::{VaultServiceError, VaultServiceHandle};

#[test]
fn test_full_lifecycle() {
    let service = VaultServiceHandle::new();

    // Starts locked
    assert!(!service.is_unlocked());

    // Can't derive while locked
    let result = service.derive_ed25519(PATHS::IDENTITY);
    assert!(matches!(result, Err(VaultServiceError::VaultLocked)));

    // Unlock
    let phrase = service.unlock_new(24).unwrap();
    assert!(service.is_unlocked());
    assert!(!phrase.is_empty());

    // Can derive while unlocked
    let key = service.derive_ed25519(PATHS::IDENTITY).unwrap();
    assert!(!key.private_key.is_empty());

    // Lock
    service.lock();
    assert!(!service.is_unlocked());

    // Can't derive again
    let result = service.derive_ed25519(PATHS::IDENTITY);
    assert!(matches!(result, Err(VaultServiceError::VaultLocked)));
}

#[test]
fn test_unlock_with_known_phrase() {
    let service = VaultServiceHandle::new();

    // Generate a phrase
    let phrase = service.unlock_new(24).unwrap();
    service.lock();

    // Re-unlock with the same phrase
    service.unlock(&phrase, None).unwrap();
    assert!(service.is_unlocked());

    // Different passphrase produces different seed
    // (tested by deriving keys with different passphrases)
}

#[test]
fn test_double_unlock_fails() {
    let service = VaultServiceHandle::new();
    service.unlock_new(24).unwrap();

    let result = service.unlock_new(12);
    assert!(matches!(result, Err(VaultServiceError::AlreadyUnlocked)));
}

#[test]
fn test_lock_when_already_locked_is_noop() {
    let service = VaultServiceHandle::new();
    assert!(!service.is_unlocked());

    // Lock on already-locked service is a no-op
    service.lock();
    assert!(!service.is_unlocked());
}

#[test]
fn test_encrypt_decrypt_lifecycle() {
    let service = VaultServiceHandle::new();
    service.unlock_new(24).unwrap();

    let plaintext = "my-api-key-12345";
    let encrypted = service.encrypt(plaintext, 2).unwrap();
    let decrypted = service.decrypt(&encrypted).unwrap();
    assert_eq!(decrypted, plaintext);

    // After lock, can't decrypt
    service.lock();
    let result = service.decrypt(&encrypted);
    assert!(matches!(result, Err(VaultServiceError::VaultLocked)));
}

#[test]
fn test_multiple_derive_paths_succeed() {
    let service = VaultServiceHandle::new();
    service.unlock_new(24).unwrap();

    // All standard paths should work
    let _identity = service.derive_ed25519(PATHS::IDENTITY).unwrap();
    let _ssh = service.derive_ed25519(PATHS::SSH_HOST).unwrap();
    let _enc = service.derive_encryption_key(PATHS::ENCRYPTION).unwrap();
}
