#![allow(unexpected_cfgs)]
#![cfg(feature = "__trading_service_integration")]
//! Comprehensive Authentication Edge Case Tests for Trading Service
//!
//! This test suite covers critical edge cases, failures, and concurrent scenarios:
//! - Concurrent authentication (race conditions, thundering herd)
//! - Network failures (Redis, database, partial partitions)
//! - Redis failures (OOM, restart, corrupted data, TTL edge cases)
//! - Timeout scenarios (extremely short, long, partial operations)
//!
//! Test Coverage: 30 comprehensive edge case tests
//! Focus: HFT requirements (<10μs latency, 100K req/s, zero data races)

use anyhow::Result;
use jsonwebtoken::{encode, EncodingKey, Header};
use std::net::IpAddr;
use std::sync::Arc;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use tokio::task::JoinSet;
use tokio::time::{sleep, timeout};
use uuid::Uuid;

use trading_service::auth_interceptor::{AuthConfig, JwtClaims, JwtValidator};
use trading_service::rate_limiter::{
    RateLimitConfig, RateLimitContext, RateLimitResult, RateLimiter, RequestType,
};

// ============================================================================
// TEST HELPERS & FIXTURES
// ============================================================================

/// Test JWT secret that meets all validation requirements
const TEST_JWT_SECRET: &str =
    "Kx7mP@9nR!2sW#5vY$8bC&3fG*6jH^1kL%4pQ+7tZ-0uN~9dM=5eV(8xS)2wT!6yA#4zB";

/// Helper to create valid JWT token for testing
fn create_test_jwt_token(secret: &str, modify_claims: impl FnOnce(&mut JwtClaims)) -> String {
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();

    let mut claims = JwtClaims {
        jti: format!("test-jti-{}", Uuid::new_v4()),
        sub: "test_user_123".to_string(),
        iat: now,
        exp: now + 3600, // 1 hour expiration
        iss: "foxhunt-trading".to_string(),
        aud: "trading-api".to_string(),
        roles: vec!["trader".to_string()],
        permissions: vec!["trading.submit_order".to_string()],
        token_type: "access".to_string(),
        session_id: Some(format!("session-{}", Uuid::new_v4())),
    };

    modify_claims(&mut claims);

    let key = EncodingKey::from_secret(secret.as_ref());
    encode(&Header::default(), &claims, &key).expect("Failed to encode JWT")
}

/// Helper to create AuthConfig with test-safe defaults
fn create_test_auth_config() -> AuthConfig {
    std::env::set_var("JWT_SECRET", TEST_JWT_SECRET);
    let mut config = AuthConfig::new().expect("Failed to create AuthConfig");
    config.require_mtls = false;
    config
}

// ============================================================================
// CATEGORY 1: CONCURRENT AUTHENTICATION (10 tests)
// ============================================================================

#[tokio::test]
async fn test_concurrent_thundering_herd_1000_simultaneous_logins() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Create 1000 valid tokens
    let tokens: Vec<String> = (0..1000)
        .map(|i| {
            create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = format!("user_{}", i);
                claims.jti = format!("jti-{}", Uuid::new_v4());
            })
        })
        .collect();

    // Spawn 1000 concurrent validation tasks
    let mut tasks = JoinSet::new();
    for (i, token) in tokens.into_iter().enumerate() {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move {
            let result = validator_clone.validate_token(&token).await;
            (i, result.is_ok())
        });
    }

    // Collect results
    let mut success_count = 0;
    while let Some(result) = tasks.join_next().await {
        let (_index, is_ok) = result.unwrap();
        if is_ok {
            success_count += 1;
        }
    }

    // All 1000 should succeed
    assert_eq!(success_count, 1000, "Expected all 1000 logins to succeed");

    Ok(())
}

#[tokio::test]
async fn test_concurrent_race_condition_token_generation() -> Result<()> {
    let config = Arc::new(create_test_auth_config());

    // Spawn 100 concurrent token generation tasks for the SAME user
    let mut tasks = JoinSet::new();
    for _ in 0..100 {
        tasks.spawn(async move {
            create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = "shared_user_123".to_string();
                // Each token should get a unique JTI
                claims.jti = format!("jti-{}", Uuid::new_v4());
            })
        });
    }

    // Collect all generated tokens
    let mut tokens = Vec::new();
    while let Some(result) = tasks.join_next().await {
        tokens.push(result.unwrap());
    }

    // Verify all tokens are unique and valid
    assert_eq!(tokens.len(), 100);

    let validator = JwtValidator::new(config);
    let mut unique_jtis = std::collections::HashSet::new();

    for token in tokens {
        let claims = validator.validate_token(&token).await?;
        assert_eq!(claims.sub, "shared_user_123");
        unique_jtis.insert(claims.jti.clone());
    }

    // All JTIs should be unique
    assert_eq!(unique_jtis.len(), 100, "Expected 100 unique JTI values");

    Ok(())
}

#[tokio::test]
async fn test_concurrent_rate_limiter_no_data_races() -> Result<()> {
    let config = RateLimitConfig {
        user_requests_per_minute: 100,
        user_burst_capacity: 100,
        ip_requests_per_minute: 100,
        ip_burst_capacity: 100,
        ..Default::default()
    };
    let limiter = Arc::new(RateLimiter::new(config));

    let test_ip: IpAddr = "192.168.1.200".parse().expect("INVARIANT: Valid parse input");

    // Spawn 200 concurrent rate limit checks
    let mut tasks = JoinSet::new();
    for _ in 0..200 {
        let limiter_clone = Arc::clone(&limiter);
        tasks.spawn(async move {
            let context = RateLimitContext {
                user_id: None,
                ip_addr: test_ip,
                request_type: RequestType::General,
                tokens_requested: 1.0,
            };
            let result = limiter_clone.check_rate_limit(&context).await;
            matches!(result, RateLimitResult::Allowed)
        });
    }

    // Collect results
    let mut allowed_count = 0;
    let mut blocked_count = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            allowed_count += 1;
        } else {
            blocked_count += 1;
        }
    }

    // First 100 allowed, next 100 blocked (burst capacity)
    assert!(
        allowed_count <= 100,
        "Expected at most 100 allowed requests"
    );
    assert!(
        blocked_count >= 100,
        "Expected at least 100 blocked requests"
    );
    assert_eq!(allowed_count + blocked_count, 200, "Total should be 200");

    Ok(())
}

#[tokio::test]
async fn test_concurrent_jwt_validation_same_token() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Create a single valid token
    let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});

    // Validate it 500 times concurrently
    let mut tasks = JoinSet::new();
    for _ in 0..500 {
        let validator_clone = Arc::clone(&validator);
        let token_clone = token.clone();
        tasks.spawn(async move { validator_clone.validate_token(&token_clone).await.is_ok() });
    }

    // All should succeed
    let mut success_count = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            success_count += 1;
        }
    }

    assert_eq!(
        success_count, 500,
        "Expected all 500 validations to succeed"
    );

    Ok(())
}

#[tokio::test]
async fn test_concurrent_mixed_valid_invalid_tokens() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Create 250 valid and 250 invalid tokens
    let mut tokens = Vec::new();

    for i in 0..250 {
        // Valid token
        let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
            claims.sub = format!("valid_user_{}", i);
        });
        tokens.push((token, true)); // (token, expected_valid)
    }

    for i in 0..250 {
        // Invalid token (wrong signature)
        let wrong_secret = "WrongSecret123!@#WrongSecret123!@#WrongSecret123!@#WrongSecret123!@#";
        let token = create_test_jwt_token(wrong_secret, |claims| {
            claims.sub = format!("invalid_user_{}", i);
        });
        tokens.push((token, false));
    }

    // Validate all 500 concurrently
    let mut tasks = JoinSet::new();
    for (token, expected_valid) in tokens {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move {
            let result = validator_clone.validate_token(&token).await;
            (result.is_ok(), expected_valid)
        });
    }

    // Verify results
    let mut valid_count = 0;
    let mut invalid_count = 0;
    while let Some(result) = tasks.join_next().await {
        let (is_ok, expected_valid) = result.unwrap();
        assert_eq!(is_ok, expected_valid, "Validation result mismatch");
        if is_ok {
            valid_count += 1;
        } else {
            invalid_count += 1;
        }
    }

    assert_eq!(valid_count, 250);
    assert_eq!(invalid_count, 250);

    Ok(())
}

#[tokio::test]
async fn test_concurrent_token_refresh_stampede() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Create 1000 tokens that will expire at approximately the same time
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let expiry = now + 2; // Expire in 2 seconds

    let tokens: Vec<String> = (0..1000)
        .map(|i| {
            create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = format!("user_{}", i);
                claims.exp = expiry;
            })
        })
        .collect();

    // Wait 3 seconds for tokens to expire
    sleep(Duration::from_secs(3)).await;

    // Attempt to validate all expired tokens concurrently (simulating refresh stampede)
    let mut tasks = JoinSet::new();
    for token in tokens {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move { validator_clone.validate_token(&token).await.is_err() });
    }

    // All should fail (expired)
    let mut failed_count = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            failed_count += 1;
        }
    }

    assert_eq!(
        failed_count, 1000,
        "Expected all 1000 expired tokens to fail"
    );

    Ok(())
}

#[tokio::test]
async fn test_concurrent_rate_limit_different_ips_independent() -> Result<()> {
    let config = RateLimitConfig {
        user_requests_per_minute: 10,
        user_burst_capacity: 10,
        ip_requests_per_minute: 10,
        ip_burst_capacity: 10,
        ..Default::default()
    };
    let limiter = Arc::new(RateLimiter::new(config));

    // Spawn 50 IPs making 20 requests each concurrently
    let mut tasks = JoinSet::new();
    for ip_suffix in 0..50 {
        let limiter_clone = Arc::clone(&limiter);
        tasks.spawn(async move {
            let test_ip: IpAddr = format!("192.168.1.{}", ip_suffix).parse().expect("INVARIANT: Valid parse input");
            let mut allowed = 0;
            for _ in 0..20 {
                let context = RateLimitContext {
                    user_id: None,
                    ip_addr: test_ip,
                    request_type: RequestType::General,
                    tokens_requested: 1.0,
                };
                let result = limiter_clone.check_rate_limit(&context).await;
                if matches!(result, RateLimitResult::Allowed) {
                    allowed += 1;
                }
            }
            (ip_suffix, allowed)
        });
    }

    // Each IP should get exactly 10 allowed (burst capacity)
    while let Some(result) = tasks.join_next().await {
        let (_ip, allowed) = result.unwrap();
        assert_eq!(allowed, 10, "Each IP should get exactly 10 requests");
    }

    Ok(())
}

#[tokio::test]
async fn test_concurrent_auth_failure_lockout() -> Result<()> {
    let config = RateLimitConfig {
        user_requests_per_minute: 100,
        user_burst_capacity: 100,
        ip_requests_per_minute: 100,
        ip_burst_capacity: 100,
        auth_failures_per_minute: 5,
        auth_failure_penalty_minutes: 1,
        ..Default::default()
    };
    let limiter = Arc::new(RateLimiter::new(config));

    let test_ip: IpAddr = "192.168.1.201".parse().expect("INVARIANT: Valid parse input");

    // 10 concurrent tasks recording auth failures
    let mut tasks = JoinSet::new();
    for _ in 0..10 {
        let limiter_clone = Arc::clone(&limiter);
        tasks.spawn(async move {
            let user_id = Uuid::new_v4();
            limiter_clone
                .apply_auth_failure_penalty(user_id, test_ip)
                .await;
        });
    }

    // Wait for all to complete
    while tasks.join_next().await.is_some() {}

    // Check if IP is locked out
    let context = RateLimitContext {
        user_id: None,
        ip_addr: test_ip,
        request_type: RequestType::General,
        tokens_requested: 1.0,
    };
    let result = limiter.check_rate_limit(&context).await;
    assert!(
        !matches!(result, RateLimitResult::Allowed),
        "IP should be locked out after 10 failures"
    );

    Ok(())
}

#[tokio::test]
async fn test_concurrent_jwt_expiration_boundary() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Create token that expires in exactly 1 second
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
        claims.exp = now + 1;
    });

    // Spawn 100 tasks to validate at exactly the same time
    let mut tasks = JoinSet::new();
    for _ in 0..100 {
        let validator_clone = Arc::clone(&validator);
        let token_clone = token.clone();
        tasks.spawn(async move { validator_clone.validate_token(&token_clone).await.is_ok() });
    }

    // Immediately collect results (before expiration)
    let mut initial_success = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            initial_success += 1;
        }
    }

    // All should succeed (not expired yet)
    assert_eq!(initial_success, 100);

    // Wait for expiration
    sleep(Duration::from_secs(2)).await;

    // Try again - all should fail
    let mut tasks = JoinSet::new();
    for _ in 0..100 {
        let validator_clone = Arc::clone(&validator);
        let token_clone = token.clone();
        tasks.spawn(async move { validator_clone.validate_token(&token_clone).await.is_err() });
    }

    let mut expired_failures = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            expired_failures += 1;
        }
    }

    assert_eq!(expired_failures, 100, "All should fail after expiration");

    Ok(())
}

#[tokio::test]
async fn test_concurrent_multiple_roles_permission_checks() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    let roles = vec!["admin", "trader", "analyst", "risk_manager"];

    // Spawn 200 concurrent validations (50 per role)
    let mut tasks = JoinSet::new();
    for i in 0..200 {
        let role = roles[i % 4];
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move {
            let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.roles = vec![role.to_string()];
            });
            let result = validator_clone.validate_token(&token).await;
            (role, result.is_ok())
        });
    }

    // All should succeed with correct roles
    let mut role_counts = std::collections::HashMap::new();
    while let Some(result) = tasks.join_next().await {
        let (role, is_ok) = result.unwrap();
        assert!(is_ok, "Validation should succeed for role {}", role);
        *role_counts.entry(role).or_insert(0) += 1;
    }

    // Each role should have exactly 50 validations
    for role in roles {
        assert_eq!(
            role_counts[role], 50,
            "Expected 50 validations for role {}",
            role
        );
    }

    Ok(())
}

// ============================================================================
// CATEGORY 2: NETWORK FAILURES (8 tests)
// ============================================================================

#[tokio::test]
async fn test_network_timeout_extremely_slow_validation() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});

    // Set a very short timeout (10ms)
    let result = timeout(Duration::from_millis(10), validator.validate_token(&token)).await;

    // Should complete within 10ms (HFT requirement)
    assert!(result.is_ok(), "Validation should complete within 10ms");
    assert!(result.unwrap().is_ok(), "Token should be valid");

    Ok(())
}

#[tokio::test]
async fn test_network_validation_under_latency_spike() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Simulate network latency spike by running 1000 concurrent validations
    let mut tasks = JoinSet::new();
    for _ in 0..1000 {
        let validator_clone = Arc::clone(&validator);
        let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});
        tasks.spawn(async move {
            let start = std::time::Instant::now();
            let result = validator_clone.validate_token(&token).await;
            (result.is_ok(), start.elapsed())
        });
    }

    let mut max_latency = Duration::from_secs(0);
    let mut success_count = 0;
    while let Some(result) = tasks.join_next().await {
        let (is_ok, latency) = result.unwrap();
        if is_ok {
            success_count += 1;
        }
        if latency > max_latency {
            max_latency = latency;
        }
    }

    assert_eq!(success_count, 1000, "All validations should succeed");
    // P99 should be < 10μs, but under load we allow < 1ms
    assert!(
        max_latency < Duration::from_millis(1),
        "Max latency should be < 1ms"
    );

    Ok(())
}

#[tokio::test]
async fn test_network_partial_token_corruption() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    let valid_token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});

    // Simulate network corruption by modifying random characters
    let mut corrupted = valid_token.clone();
    let bytes = unsafe { corrupted.as_bytes_mut() };
    if !bytes.is_empty() {
        bytes[bytes.len() / 2] = b'X'; // Corrupt middle character
    }

    // Corrupted token should fail validation
    let result = validator.validate_token(&corrupted).await;
    assert!(result.is_err(), "Corrupted token should fail validation");

    // Original should still work
    let result = validator.validate_token(&valid_token).await;
    assert!(result.is_ok(), "Original token should remain valid");

    Ok(())
}

#[tokio::test]
async fn test_network_connection_pool_exhaustion() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Spawn 10,000 concurrent validation tasks (stress test)
    let mut tasks = JoinSet::new();
    for i in 0..10000 {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move {
            let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = format!("user_{}", i);
            });
            validator_clone.validate_token(&token).await.is_ok()
        });
    }

    // System should handle all requests without exhaustion
    let mut success_count = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            success_count += 1;
        }
    }

    assert!(
        success_count >= 9500,
        "At least 95% should succeed under stress (got {})",
        success_count
    );

    Ok(())
}

#[tokio::test]
async fn test_network_dns_resolution_timeout() -> Result<()> {
    // This test verifies auth does NOT depend on DNS resolution
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});

    // Should complete instantly (no DNS lookups)
    let start = std::time::Instant::now();
    let result = validator.validate_token(&token).await;
    let elapsed = start.elapsed();

    assert!(result.is_ok(), "Validation should succeed");
    assert!(
        elapsed < Duration::from_micros(100),
        "Should be < 100μs (no network)"
    );

    Ok(())
}

#[tokio::test]
async fn test_network_packet_loss_simulation() -> Result<()> {
    // Simulate intermittent network by randomly failing some validations
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    let mut tasks = JoinSet::new();
    for i in 0..100 {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move {
            let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});
            // Simulate packet loss: every 10th request "fails" (we return error)
            if i % 10 == 0 {
                Err::<(), anyhow::Error>(anyhow::anyhow!("Simulated packet loss"))
            } else {
                validator_clone.validate_token(&token).await.map(|_| ())
            }
        });
    }

    let mut success_count = 0;
    let mut simulated_loss = 0;
    while let Some(result) = tasks.join_next().await {
        match result.unwrap() {
            Ok(_) => success_count += 1,
            Err(_) => simulated_loss += 1,
        }
    }

    assert_eq!(simulated_loss, 10, "Expected 10 simulated packet losses");
    assert_eq!(success_count, 90, "Expected 90 successful validations");

    Ok(())
}

#[tokio::test]
async fn test_network_tls_handshake_overhead() -> Result<()> {
    // Verify JWT validation is fast (no TLS handshake overhead)
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});

    // 1000 sequential validations should be very fast
    let start = std::time::Instant::now();
    for _ in 0..1000 {
        validator.validate_token(&token).await?;
    }
    let elapsed = start.elapsed();

    // Average should be < 10μs per validation
    let avg = elapsed / 1000;
    assert!(
        avg < Duration::from_micros(10),
        "Average validation should be < 10μs (got {:?})",
        avg
    );

    Ok(())
}

#[tokio::test]
async fn test_network_graceful_degradation_under_load() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Spawn 5000 concurrent tasks in waves
    let mut all_tasks = JoinSet::new();
    for wave in 0..5 {
        sleep(Duration::from_millis(10)).await; // Small delay between waves
        for i in 0..1000 {
            let validator_clone = Arc::clone(&validator);
            all_tasks.spawn(async move {
                let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                    claims.sub = format!("user_wave{}_{}", wave, i);
                });
                validator_clone.validate_token(&token).await.is_ok()
            });
        }
    }

    let mut success_count = 0;
    while let Some(result) = all_tasks.join_next().await {
        if result.unwrap() {
            success_count += 1;
        }
    }

    // Should handle 5000 requests with >99% success
    assert!(
        success_count >= 4950,
        "Expected >99% success under wave load (got {})",
        success_count
    );

    Ok(())
}

// ============================================================================
// CATEGORY 3: TIMEOUT EDGE CASES (5 tests)
// ============================================================================

#[tokio::test]
async fn test_timeout_extremely_short_1ms_validation() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});

    // Set 1ms timeout (very aggressive for HFT)
    let result = timeout(Duration::from_millis(1), validator.validate_token(&token)).await;

    // Should complete within 1ms
    assert!(result.is_ok(), "Validation should complete within 1ms");
    assert!(result.unwrap().is_ok(), "Token should be valid");

    Ok(())
}

#[tokio::test]
async fn test_timeout_long_10s_validation() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});

    // Set 10s timeout (unnecessarily long)
    let result = timeout(Duration::from_secs(10), validator.validate_token(&token)).await;

    assert!(result.is_ok(), "Validation should complete within 10s");
    assert!(result.unwrap().is_ok(), "Token should be valid");

    Ok(())
}

#[tokio::test]
async fn test_timeout_multiple_operations_cleanup() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Run 1000 validations with 1ms timeout each
    let mut tasks = JoinSet::new();
    for i in 0..1000 {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move {
            let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = format!("user_{}", i);
            });
            timeout(
                Duration::from_millis(1),
                validator_clone.validate_token(&token),
            )
            .await
        });
    }

    let mut success_count = 0;
    let mut timeout_count = 0;
    while let Some(result) = tasks.join_next().await {
        match result.unwrap() {
            Ok(Ok(_)) => success_count += 1,
            Ok(Err(_)) => {}, // Validation error (not timeout)
            Err(_) => timeout_count += 1,
        }
    }

    // Most should succeed within 1ms
    assert!(success_count >= 950, "Expected >95% to complete within 1ms");
    assert!(timeout_count < 50, "Expected <5% timeouts");

    Ok(())
}

#[tokio::test]
async fn test_timeout_validation_at_expiration_boundary() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    // Create token expiring in exactly 100ms
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
        claims.exp = now + 1; // Expires in 1 second
    });

    // Validate immediately (should succeed)
    let result = timeout(Duration::from_millis(10), validator.validate_token(&token)).await;
    assert!(result.is_ok());
    assert!(result.unwrap().is_ok());

    // Wait for expiration
    sleep(Duration::from_millis(1100)).await;

    // Validate after expiration (should fail, but quickly)
    let result = timeout(Duration::from_millis(10), validator.validate_token(&token)).await;
    assert!(result.is_ok(), "Should complete within timeout");
    assert!(result.unwrap().is_err(), "Token should be expired");

    Ok(())
}

#[tokio::test]
async fn test_timeout_concurrent_timeout_handling() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Spawn 500 tasks with varying timeouts
    let mut tasks = JoinSet::new();
    for i in 0..500 {
        let validator_clone = Arc::clone(&validator);
        let timeout_ms = 1 + (i % 10); // Timeouts from 1ms to 10ms
        tasks.spawn(async move {
            let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});
            let result = timeout(
                Duration::from_millis(timeout_ms),
                validator_clone.validate_token(&token),
            )
            .await;
            result.is_ok()
        });
    }

    let mut completed = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            completed += 1;
        }
    }

    // All should complete within their respective timeouts
    assert_eq!(
        completed, 500,
        "All validations should complete within timeout"
    );

    Ok(())
}

// ============================================================================
// CATEGORY 4: REDIS FAILURES (7 tests)
// Note: These tests simulate Redis behavior without actual Redis infrastructure
// ============================================================================

#[tokio::test]
async fn test_redis_simulated_oom_during_validation() -> Result<()> {
    // Simulate Redis OOM by creating extremely large token (>8KB)
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    let oversized_token = "a".repeat(10000); // 10KB token

    let result = validator.validate_token(&oversized_token).await;
    assert!(result.is_err(), "Oversized token should be rejected");

    Ok(())
}

#[tokio::test]
async fn test_redis_simulated_corrupted_cache_data() -> Result<()> {
    // Simulate corrupted JWT by malforming structure
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    let corrupted_token = "header.payload"; // Missing signature section

    let result = validator.validate_token(corrupted_token).await;
    assert!(result.is_err(), "Malformed token should be rejected");

    Ok(())
}

#[tokio::test]
async fn test_redis_simulated_ttl_expiration_race() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Create tokens with very short expiration (1 second)
    let now = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_secs();
    let tokens: Vec<String> = (0..100)
        .map(|i| {
            create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = format!("user_{}", i);
                claims.exp = now + 1;
            })
        })
        .collect();

    // Validate half immediately
    let mut immediate_tasks = JoinSet::new();
    for (i, token) in tokens.iter().enumerate().take(50) {
        let validator_clone = Arc::clone(&validator);
        let token_clone = token.clone();
        immediate_tasks.spawn(async move {
            (
                i,
                validator_clone.validate_token(&token_clone).await.is_ok(),
            )
        });
    }

    let mut immediate_success = 0;
    while let Some(result) = immediate_tasks.join_next().await {
        if result.unwrap().1 {
            immediate_success += 1;
        }
    }
    assert_eq!(
        immediate_success, 50,
        "All immediate validations should succeed"
    );

    // Wait for expiration
    sleep(Duration::from_millis(1100)).await;

    // Validate remaining half (should fail)
    let mut delayed_tasks = JoinSet::new();
    for (i, token) in tokens.iter().enumerate().skip(50) {
        let validator_clone = Arc::clone(&validator);
        let token_clone = token.clone();
        delayed_tasks.spawn(async move {
            (
                i,
                validator_clone.validate_token(&token_clone).await.is_err(),
            )
        });
    }

    let mut delayed_failures = 0;
    while let Some(result) = delayed_tasks.join_next().await {
        if result.unwrap().1 {
            delayed_failures += 1;
        }
    }
    assert_eq!(
        delayed_failures, 50,
        "All delayed validations should fail (expired)"
    );

    Ok(())
}

#[tokio::test]
async fn test_redis_simulated_eviction_policy_impact() -> Result<()> {
    // Simulate eviction by creating many tokens and checking they remain valid
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    let tokens: Vec<String> = (0..1000)
        .map(|i| {
            create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = format!("user_{}", i);
            })
        })
        .collect();

    // Validate all tokens (simulating cache population)
    let mut tasks = JoinSet::new();
    for token in tokens {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move { validator_clone.validate_token(&token).await.is_ok() });
    }

    let mut success_count = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            success_count += 1;
        }
    }

    // All should remain valid (no eviction in memory)
    assert_eq!(success_count, 1000, "All tokens should remain valid");

    Ok(())
}

#[tokio::test]
async fn test_redis_simulated_read_write_timeout() -> Result<()> {
    let config = Arc::new(create_test_auth_config());
    let validator = JwtValidator::new(config);

    let token = create_test_jwt_token(TEST_JWT_SECRET, |_| {});

    // Simulate timeout with extremely short duration
    let result = timeout(Duration::from_micros(1), validator.validate_token(&token)).await;

    // May timeout (acceptable) or complete (very fast)
    match result {
        Ok(Ok(_)) => {}, // Completed within 1μs (excellent)
        Err(_) => {},    // Timed out (acceptable for 1μs)
        Ok(Err(_)) => panic!("Validation should not fail"),
    }

    Ok(())
}

#[tokio::test]
async fn test_redis_simulated_cluster_failover() -> Result<()> {
    // Simulate failover by validating many tokens concurrently
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    let mut tasks = JoinSet::new();
    for i in 0..500 {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move {
            let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = format!("user_{}", i);
            });
            validator_clone.validate_token(&token).await.is_ok()
        });
    }

    let mut success_count = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            success_count += 1;
        }
    }

    // Should maintain >99% availability during "failover"
    assert!(
        success_count >= 495,
        "Expected >99% success during failover simulation"
    );

    Ok(())
}

#[tokio::test]
async fn test_redis_simulated_memory_pressure() -> Result<()> {
    // Simulate memory pressure by creating many large claims
    let config = Arc::new(create_test_auth_config());
    let validator = Arc::new(JwtValidator::new(config));

    // Create 100 tokens with large permissions lists
    let mut tasks = JoinSet::new();
    for i in 0..100 {
        let validator_clone = Arc::clone(&validator);
        tasks.spawn(async move {
            let token = create_test_jwt_token(TEST_JWT_SECRET, |claims| {
                claims.sub = format!("user_{}", i);
                // Add 100 permissions (large claim)
                claims.permissions = (0..100).map(|p| format!("permission_{}", p)).collect();
            });
            validator_clone.validate_token(&token).await.is_ok()
        });
    }

    let mut success_count = 0;
    while let Some(result) = tasks.join_next().await {
        if result.unwrap() {
            success_count += 1;
        }
    }

    // All should succeed despite large claims
    assert_eq!(
        success_count, 100,
        "All large claim validations should succeed"
    );

    Ok(())
}
