#![allow(unused_variables, unexpected_cfgs)]

use vault_service::rustyvault::RustyVaultClient;
use vault_service::types::{EncryptionContext, KeySpec};

#[test]
fn test_rustyvault_client_creation() {
    let client = RustyVaultClient::new(
        "http://localhost:8200".to_string(),
        Some("test-token".to_string()),
        "transit".to_string(),
        "test-key".to_string(),
        true,
    );

    assert!(client.is_ok());
    let _client = client.unwrap();
}

#[test]
fn test_rustyvault_client_without_token() {
    let client = RustyVaultClient::new(
        "http://localhost:8200".to_string(),
        None,
        "transit".to_string(),
        "test-key".to_string(),
        true,
    );

    assert!(client.is_ok());
}

#[test]
fn test_rustyvault_url_normalization() {
    let client = RustyVaultClient::new(
        "http://localhost:8200/".to_string(),
        Some("token".to_string()),
        "transit".to_string(),
        "test-key".to_string(),
        false,
    );

    assert!(client.is_ok());
}

#[tokio::test]
async fn test_encryption_context() {
    let mut ctx = EncryptionContext::new();
    ctx.add("environment", "test");
    ctx.add("service", "kms");

    assert_eq!(ctx.context.len(), 2);
    assert_eq!(ctx.context.get("environment").unwrap(), "test");
    assert_eq!(ctx.context.get("service").unwrap(), "kms");
}

#[test]
fn test_key_spec_sizes() {
    assert_eq!(KeySpec::Aes128.key_size(), 16);
    assert_eq!(KeySpec::Aes256.key_size(), 32);
    assert_eq!(KeySpec::Rsa2048.key_size(), 256);
    assert_eq!(KeySpec::Rsa4096.key_size(), 512);
}

// Integration tests (require running RustyVault instance)
#[cfg(feature = "integration_tests")]
mod integration {
    use super::*;

    async fn get_test_client() -> RustyVaultClient {
        let server_url = std::env::var("RUSTYVAULT_TEST_URL")
            .unwrap_or_else(|_| "http://localhost:8200".to_string());
        let token = std::env::var("RUSTYVAULT_TEST_TOKEN").ok();

        RustyVaultClient::new(
            server_url,
            token,
            "transit".to_string(),
            "test-key".to_string(),
            false,
        )
        .expect("Failed to create test client")
    }

    #[tokio::test]
    async fn test_health_check() {
        let client = get_test_client().await;
        let result = client.health_check().await;
        assert!(result.is_ok());
    }

    #[tokio::test]
    async fn test_encrypt_decrypt() {
        let client = get_test_client().await;
        let plaintext = b"Hello, RustyVault!";
        let context = EncryptionContext::new();

        let ciphertext = client
            .encrypt(plaintext, &context)
            .await
            .expect("Encryption failed");

        assert!(!ciphertext.is_empty());
        assert_ne!(ciphertext, plaintext);

        let decrypted = client
            .decrypt(&ciphertext, &context)
            .await
            .expect("Decryption failed");

        assert_eq!(decrypted, plaintext);
    }

    #[tokio::test]
    async fn test_encrypt_decrypt_with_context() {
        let client = get_test_client().await;
        let plaintext = b"Sensitive data";
        let mut context = EncryptionContext::new();
        context.add("environment", "production");
        context.add("service", "api-gateway");

        let ciphertext = client
            .encrypt(plaintext, &context)
            .await
            .expect("Encryption with context failed");

        let decrypted = client
            .decrypt(&ciphertext, &context)
            .await
            .expect("Decryption with context failed");

        assert_eq!(decrypted, plaintext);
    }

    #[tokio::test]
    async fn test_generate_data_key() {
        let client = get_test_client().await;

        let data_key = client
            .generate_data_key(&KeySpec::Aes256)
            .await
            .expect("Data key generation failed");

        assert_eq!(data_key.plaintext.len(), 32); // AES-256 = 32 bytes
        assert!(!data_key.ciphertext.is_empty());
        assert_eq!(data_key.key_id, "test-key");
    }

    #[tokio::test]
    async fn test_version_check() {
        let client = get_test_client().await;
        let version = client.get_version().await;
        assert!(version.is_ok());
    }
}
