#![allow(unused_variables)]
//! Comprehensive Authentication Edge Case Tests
//!
//! This test suite focuses on edge cases and security scenarios for the
//! API Gateway authentication system. Coverage areas:
//!
//! 1. JWT Token Edge Cases:
//!    - Expired tokens
//!    - Malformed tokens
//!    - Invalid signatures
//!    - Missing required claims
//!    - Token format validation
//!    - Token refresh scenarios
//!
//! 2. Session Management:
//!    - Session timeout
//!    - Concurrent sessions
//!    - Session invalidation
//!    - Session renewal
//!
//! 3. Rate Limiting Edge Cases:
//!    - Per-user limits
//!    - Per-IP limits
//!    - Burst handling
//!    - Rate limit reset
//!    - Concurrent rate limit checks
//!
//! 4. Request Routing:
//!    - Backend service failures
//!    - Circuit breaker activation
//!    - Timeout handling
//!    - Service discovery
//!    - Load balancing

#[path = "common/mod.rs"]
mod common;

use anyhow::Result;
use common::{
    cleanup_redis, generate_expired_token, generate_invalid_signature_token, generate_test_token,
    wait_for_redis, TestJwtConfig,
};
use jsonwebtoken::{encode, EncodingKey, Header};
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use tonic::{metadata::MetadataValue, Request};
use uuid::Uuid;

use api::auth::{
    AuditLogger, AuthInterceptor, AuthzService, Jti, JwtClaims, JwtService, RateLimiter,
    RevocationService,
};

const REDIS_URL: &str = "redis://localhost:6379";

/// Setup test authentication components
async fn setup_auth_components() -> Result<AuthInterceptor> {
    wait_for_redis(REDIS_URL, 50).await?;
    cleanup_redis(REDIS_URL).await?;

    let config = TestJwtConfig::default();

    let jwt_service = JwtService::new(config.secret, config.issuer, config.audience);

    let revocation_service = RevocationService::new(REDIS_URL).await?;
    let authz_service = AuthzService::new();
    let rate_limiter = RateLimiter::new(100).map_err(|e| anyhow::anyhow!(e))?;
    let audit_logger = AuditLogger::new(true);

    Ok(AuthInterceptor::new(
        jwt_service,
        revocation_service,
        authz_service,
        rate_limiter,
        audit_logger,
    ))
}

// ============================================================================
// JWT Token Edge Cases
// ============================================================================

#[tokio::test]
async fn test_expired_jwt_rejected() -> Result<()> {
    println!("\n=== Test: Expired JWT Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate expired token
    let token = generate_expired_token("user_expired")?;

    // Create request with expired token
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "Expired JWT should be rejected");

    if let Err(status) = result {
        assert_eq!(status.code(), tonic::Code::Unauthenticated);
        println!("✓ Expired token rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_invalid_signature_jwt_rejected() -> Result<()> {
    println!("\n=== Test: Invalid Signature JWT Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate token with invalid signature
    let token = generate_invalid_signature_token("user_invalid_sig")?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(
        result.is_err(),
        "JWT with invalid signature should be rejected"
    );

    if let Err(status) = result {
        assert_eq!(status.code(), tonic::Code::Unauthenticated);
        println!("✓ Invalid signature rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_malformed_jwt_rejected() -> Result<()> {
    println!("\n=== Test: Malformed JWT Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    // Create request with malformed token
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from("Bearer not.a.valid.jwt.token.format")?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "Malformed JWT should be rejected");

    if let Err(status) = result {
        assert_eq!(status.code(), tonic::Code::Unauthenticated);
        println!("✓ Malformed token rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_missing_jti_claim_rejected() -> Result<()> {
    println!("\n=== Test: JWT Missing JTI Claim Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    let config = TestJwtConfig::default();
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

    // Create claims without JTI (empty string)
    let claims = JwtClaims {
        jti: "".to_string(), // Invalid: empty JTI
        sub: "user_no_jti".to_string(),
        iat: now,
        exp: now + 3600,
        nbf: Some(now),
        iss: config.issuer.clone(),
        aud: config.audience.clone(),
        roles: vec!["trader".to_string()],
        permissions: vec!["api.access".to_string()],
        token_type: "access".to_string(),
        session_id: Some(Uuid::new_v4().to_string()),
    };

    let token = encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(config.secret.as_bytes()),
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "JWT without JTI should be rejected");

    if let Err(status) = result {
        println!("✓ Token without JTI rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_wrong_issuer_rejected() -> Result<()> {
    println!("\n=== Test: JWT with Wrong Issuer Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    let config = TestJwtConfig::default();
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

    // Create claims with wrong issuer
    let claims = JwtClaims {
        jti: Jti::new().0,
        sub: "user_wrong_issuer".to_string(),
        iat: now,
        exp: now + 3600,
        nbf: Some(now),
        iss: "wrong-issuer".to_string(), // Wrong issuer
        aud: config.audience.clone(),
        roles: vec!["trader".to_string()],
        permissions: vec!["api.access".to_string()],
        token_type: "access".to_string(),
        session_id: Some(Uuid::new_v4().to_string()),
    };

    let token = encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(config.secret.as_bytes()),
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "JWT with wrong issuer should be rejected");

    if let Err(status) = result {
        println!("✓ Wrong issuer rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_wrong_audience_rejected() -> Result<()> {
    println!("\n=== Test: JWT with Wrong Audience Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    let config = TestJwtConfig::default();
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

    // Create claims with wrong audience
    let claims = JwtClaims {
        jti: Jti::new().0,
        sub: "user_wrong_aud".to_string(),
        iat: now,
        exp: now + 3600,
        nbf: Some(now),
        iss: config.issuer.clone(),
        aud: "wrong-audience".to_string(), // Wrong audience
        roles: vec!["trader".to_string()],
        permissions: vec!["api.access".to_string()],
        token_type: "access".to_string(),
        session_id: Some(Uuid::new_v4().to_string()),
    };

    let token = encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(config.secret.as_bytes()),
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(
        result.is_err(),
        "JWT with wrong audience should be rejected"
    );

    if let Err(status) = result {
        println!("✓ Wrong audience rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_token_not_yet_valid_rejected() -> Result<()> {
    println!("\n=== Test: JWT Not Yet Valid (nbf) Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    let config = TestJwtConfig::default();
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

    // Create claims with future nbf (not before)
    let claims = JwtClaims {
        jti: Jti::new().0,
        sub: "user_future_nbf".to_string(),
        iat: now,
        exp: now + 7200,
        nbf: Some(now + 3600), // Valid only in 1 hour
        iss: config.issuer.clone(),
        aud: config.audience.clone(),
        roles: vec!["trader".to_string()],
        permissions: vec!["api.access".to_string()],
        token_type: "access".to_string(),
        session_id: Some(Uuid::new_v4().to_string()),
    };

    let token = encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(config.secret.as_bytes()),
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "JWT not yet valid should be rejected");

    if let Err(status) = result {
        println!("✓ Not-yet-valid token rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_missing_authorization_header() -> Result<()> {
    println!("\n=== Test: Missing Authorization Header ===");

    let auth_interceptor = setup_auth_components().await?;

    // Create request without Authorization header
    let request = Request::new(());

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(
        result.is_err(),
        "Request without auth header should be rejected"
    );

    if let Err(status) = result {
        assert_eq!(status.code(), tonic::Code::Unauthenticated);
        println!("✓ Missing auth header rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_invalid_authorization_format() -> Result<()> {
    println!("\n=== Test: Invalid Authorization Format ===");

    let auth_interceptor = setup_auth_components().await?;

    // Create request with invalid format (missing "Bearer ")
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from("InvalidFormat token")?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "Invalid auth format should be rejected");

    if let Err(status) = result {
        println!("✓ Invalid format rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_empty_bearer_token() -> Result<()> {
    println!("\n=== Test: Empty Bearer Token ===");

    let auth_interceptor = setup_auth_components().await?;

    // Create request with empty token
    let mut request = Request::new(());
    request
        .metadata_mut()
        .insert("authorization", MetadataValue::try_from("Bearer ")?);

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "Empty bearer token should be rejected");

    if let Err(status) = result {
        println!("✓ Empty token rejected: {}", status.message());
    }

    Ok(())
}

// ============================================================================
// Session Management Edge Cases
// ============================================================================

#[tokio::test]
async fn test_concurrent_sessions_same_user() -> Result<()> {
    println!("\n=== Test: Concurrent Sessions for Same User ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate two tokens for same user with different session IDs
    let (token1, _jti1) = generate_test_token(
        "user_concurrent",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    let (token2, _jti2) = generate_test_token(
        "user_concurrent",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    // First session request
    let mut request1 = Request::new(());
    request1.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token1))?,
    );

    // Second session request
    let mut request2 = Request::new(());
    request2.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token2))?,
    );

    // Both sessions should be valid
    let result1 = auth_interceptor.clone().authenticate(request1).await;
    let result2 = auth_interceptor.clone().authenticate(request2).await;

    assert!(result1.is_ok(), "First concurrent session should succeed");
    assert!(result2.is_ok(), "Second concurrent session should succeed");

    println!("✓ Both concurrent sessions validated successfully");

    Ok(())
}

#[tokio::test]
async fn test_session_invalidation_revokes_token() -> Result<()> {
    println!("\n=== Test: Session Invalidation Revokes Token ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate token
    let (token, jti) = generate_test_token(
        "user_session_invalidate",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    // First request should succeed
    let mut request1 = Request::new(());
    request1.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result1 = auth_interceptor.clone().authenticate(request1).await;
    assert!(result1.is_ok(), "First request should succeed");
    println!("✓ Token validated successfully");

    // Revoke the token (simulate session invalidation)
    let revocation_service = RevocationService::new(REDIS_URL).await?;
    revocation_service
        .revoke_token(&Jti::from_string(jti), 3600)
        .await?;
    println!("✓ Token revoked (session invalidated)");

    // Second request should fail
    let mut request2 = Request::new(());
    request2.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result2 = auth_interceptor.clone().authenticate(request2).await;
    assert!(result2.is_err(), "Revoked token should be rejected");

    if let Err(status) = result2 {
        println!("✓ Revoked token rejected: {}", status.message());
    }

    Ok(())
}

// ============================================================================
// Rate Limiting Edge Cases
// ============================================================================

#[tokio::test]
async fn test_rate_limit_per_user_independence() -> Result<()> {
    println!("\n=== Test: Rate Limit Per-User Independence ===");

    let auth_interceptor = setup_auth_components().await?;

    // Create rate limiter with very low limit (5 req/s) for testing
    let rate_limiter = RateLimiter::new(5).map_err(|e| anyhow::anyhow!(e))?;

    // User 1: Make requests until rate limited
    let mut user1_allowed = 0;
    for _ in 0..10 {
        if rate_limiter.check_rate_limit("user_1") {
            user1_allowed += 1;
        }
    }

    // User 2: Should have independent rate limit
    let mut user2_allowed = 0;
    for _ in 0..10 {
        if rate_limiter.check_rate_limit("user_2") {
            user2_allowed += 1;
        }
    }

    println!("  User 1 allowed: {} requests", user1_allowed);
    println!("  User 2 allowed: {} requests", user2_allowed);

    // Both users should be able to make requests despite the other being limited
    assert!(user1_allowed > 0, "User 1 should be allowed some requests");
    assert!(user2_allowed > 0, "User 2 should be allowed some requests");
    assert!(user1_allowed <= 5, "User 1 should be rate limited");
    assert!(user2_allowed <= 5, "User 2 should be rate limited");

    println!("✓ Per-user rate limits are independent");

    Ok(())
}

#[tokio::test]
async fn test_rate_limit_burst_handling() -> Result<()> {
    println!("\n=== Test: Rate Limit Burst Handling ===");

    let rate_limiter = RateLimiter::new(10).map_err(|e| anyhow::anyhow!(e))?; // 10 req/s

    // Make burst of 20 requests
    let mut allowed = 0;
    let mut denied = 0;

    for _ in 0..20 {
        if rate_limiter.check_rate_limit("user_burst") {
            allowed += 1;
        } else {
            denied += 1;
        }
    }

    println!("  Burst: {} allowed, {} denied", allowed, denied);

    assert!(allowed <= 10, "Burst should be limited to capacity");
    assert!(denied > 0, "Some requests should be denied");

    println!("✓ Burst correctly limited");

    Ok(())
}

#[tokio::test]
async fn test_rate_limit_reset_after_time() -> Result<()> {
    println!("\n=== Test: Rate Limit Reset After Time ===");

    let rate_limiter = RateLimiter::new(5).map_err(|e| anyhow::anyhow!(e))?; // 5 req/s

    // Exhaust rate limit
    let mut first_batch = 0;
    for _ in 0..10 {
        if rate_limiter.check_rate_limit("user_reset") {
            first_batch += 1;
        }
    }

    println!("  First batch: {} allowed", first_batch);
    assert!(first_batch <= 5, "Should be rate limited");

    // Wait for rate limit to reset (1 second)
    println!("  Waiting 1 second for rate limit reset...");
    tokio::time::sleep(Duration::from_millis(1100)).await;

    // Try again - should allow more requests
    let mut second_batch = 0;
    for _ in 0..10 {
        if rate_limiter.check_rate_limit("user_reset") {
            second_batch += 1;
        }
    }

    println!("  Second batch: {} allowed", second_batch);
    assert!(second_batch > 0, "Rate limit should have reset");

    println!("✓ Rate limit reset successfully");

    Ok(())
}

#[tokio::test]
async fn test_concurrent_rate_limit_checks() -> Result<()> {
    println!("\n=== Test: Concurrent Rate Limit Checks ===");

    let rate_limiter = RateLimiter::new(50).map_err(|e| anyhow::anyhow!(e))?; // 50 req/s

    // Spawn 100 concurrent tasks
    let mut handles = vec![];

    for _ in 0..100 {
        let limiter = rate_limiter.clone();
        let handle = tokio::spawn(async move { limiter.check_rate_limit("user_concurrent") });
        handles.push(handle);
    }

    // Collect results
    let mut allowed = 0;
    for handle in handles {
        if let Ok(true) = handle.await {
            allowed += 1;
        }
    }

    println!("  Concurrent: {} / 100 allowed", allowed);

    // Should be approximately limited to 50
    assert!(allowed >= 45, "Should allow close to rate limit");
    assert!(allowed <= 55, "Should not significantly exceed rate limit");

    println!("✓ Concurrent rate limiting working correctly");

    Ok(())
}

// ============================================================================
// Authorization Edge Cases
// ============================================================================

#[tokio::test]
async fn test_insufficient_permissions_rejected() -> Result<()> {
    println!("\n=== Test: Insufficient Permissions Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate token with minimal permissions
    let (token, _jti) = generate_test_token(
        "user_no_perms",
        vec!["viewer".to_string()],     // Only viewer role
        vec!["api.access".to_string()], // Only basic access
        3600,
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    // Token should be valid but have limited permissions
    let result = auth_interceptor.clone().authenticate(request).await;

    // Authentication succeeds, but user context reflects limited permissions
    if let Ok(authenticated_request) = result {
        let extensions = authenticated_request.extensions();
        if let Some(user_ctx) = extensions.get::<api::auth::UserContext>() {
            assert_eq!(user_ctx.roles, vec!["viewer".to_string()]);
            assert!(!user_ctx.permissions.contains(&"trading.submit".to_string()));
            println!(
                "✓ User authenticated with limited permissions: {:?}",
                user_ctx.permissions
            );
        }
    } else {
        panic!("Authentication should succeed even with limited permissions");
    }

    Ok(())
}

#[tokio::test]
async fn test_empty_roles_accepted() -> Result<()> {
    println!("\n=== Test: Empty Roles Still Authenticated ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate token with no roles
    let (token, _jti) = generate_test_token(
        "user_no_roles",
        vec![], // No roles
        vec!["api.access".to_string()],
        3600,
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(
        result.is_ok(),
        "User with no roles should still authenticate"
    );

    if let Ok(authenticated_request) = result {
        let extensions = authenticated_request.extensions();
        if let Some(user_ctx) = extensions.get::<api::auth::UserContext>() {
            assert!(user_ctx.roles.is_empty());
            println!("✓ User authenticated with no roles");
        }
    }

    Ok(())
}

// ============================================================================
// Additional JWT Edge Cases (Wave 1 Agent 8)
// ============================================================================

#[tokio::test]
async fn test_token_with_future_iat_rejected() -> Result<()> {
    println!("\n=== Test: JWT with Future IAT (Issued At) Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    let config = TestJwtConfig::default();
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

    // Create claims with future iat (issued 1 hour in the future)
    let claims = JwtClaims {
        jti: Jti::new().0,
        sub: "user_future_iat".to_string(),
        iat: now + 3600, // Issued 1 hour in the future
        exp: now + 7200, // Valid for 2 hours
        nbf: Some(now),
        iss: config.issuer.clone(),
        aud: config.audience.clone(),
        roles: vec!["trader".to_string()],
        permissions: vec!["api.access".to_string()],
        token_type: "access".to_string(),
        session_id: Some(Uuid::new_v4().to_string()),
    };

    let token = encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(config.secret.as_bytes()),
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "JWT with future iat should be rejected");

    if let Err(status) = result {
        println!("✓ Token with future iat rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_token_too_old_rejected() -> Result<()> {
    println!("\n=== Test: JWT Too Old (>1 hour) Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    let config = TestJwtConfig::default();
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

    // Create claims with old iat (issued 2 hours ago, max age is 1 hour)
    let claims = JwtClaims {
        jti: Jti::new().0,
        sub: "user_old_token".to_string(),
        iat: now - 7200, // Issued 2 hours ago
        exp: now + 3600, // Still valid for 1 hour
        nbf: Some(now - 7200),
        iss: config.issuer.clone(),
        aud: config.audience.clone(),
        roles: vec!["trader".to_string()],
        permissions: vec!["api.access".to_string()],
        token_type: "access".to_string(),
        session_id: Some(Uuid::new_v4().to_string()),
    };

    let token = encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(config.secret.as_bytes()),
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "JWT older than 1 hour should be rejected");

    if let Err(status) = result {
        println!("✓ Token too old rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_token_too_long_rejected() -> Result<()> {
    println!("\n=== Test: JWT Token Too Long (>8192 chars) Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    // Create an excessively long token (potential DoS attack)
    let long_token = "a".repeat(8200);

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", long_token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "Excessively long JWT should be rejected");

    if let Err(status) = result {
        println!("✓ Token too long rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_token_with_empty_subject_rejected() -> Result<()> {
    println!("\n=== Test: JWT with Empty Subject Claim Rejected ===");

    let auth_interceptor = setup_auth_components().await?;

    let config = TestJwtConfig::default();
    let now = SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs();

    // Create claims with empty subject
    let claims = JwtClaims {
        jti: Jti::new().0,
        sub: "".to_string(), // Empty subject
        iat: now,
        exp: now + 3600,
        nbf: Some(now),
        iss: config.issuer.clone(),
        aud: config.audience.clone(),
        roles: vec!["trader".to_string()],
        permissions: vec!["api.access".to_string()],
        token_type: "access".to_string(),
        session_id: Some(Uuid::new_v4().to_string()),
    };

    let token = encode(
        &Header::default(),
        &claims,
        &EncodingKey::from_secret(config.secret.as_bytes()),
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(result.is_err(), "JWT with empty subject should be rejected");

    if let Err(status) = result {
        println!("✓ Token with empty subject rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_token_with_corrupted_payload() -> Result<()> {
    println!("\n=== Test: JWT with Corrupted Payload ===");

    let auth_interceptor = setup_auth_components().await?;

    // Create a token with corrupted base64 payload
    let corrupted_token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.CORRUPTED!!!.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c";

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", corrupted_token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    assert!(
        result.is_err(),
        "JWT with corrupted payload should be rejected"
    );

    if let Err(status) = result {
        println!("✓ Corrupted payload rejected: {}", status.message());
    }

    Ok(())
}

#[tokio::test]
async fn test_token_with_missing_permissions_claim() -> Result<()> {
    println!("\n=== Test: JWT with Empty Permissions List ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate token with no permissions
    let (token, _jti) = generate_test_token(
        "user_no_perms",
        vec!["trader".to_string()],
        vec![], // Empty permissions
        3600,
    )?;

    // Create request
    let mut request = Request::new(());
    request.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result = auth_interceptor.clone().authenticate(request).await;

    // Should fail because api.access permission is required
    assert!(
        result.is_err(),
        "JWT without api.access permission should be rejected"
    );

    if let Err(status) = result {
        assert_eq!(status.code(), tonic::Code::PermissionDenied);
        println!(
            "✓ Token without required permissions rejected: {}",
            status.message()
        );
    }

    Ok(())
}

#[tokio::test]
async fn test_multiple_failed_authentication_attempts() -> Result<()> {
    println!("\n=== Test: Multiple Failed Authentication Attempts ===");

    let auth_interceptor = setup_auth_components().await?;

    let mut failed_attempts = 0;

    // Attempt authentication 10 times with invalid tokens
    for i in 0..10 {
        let mut request = Request::new(());
        request.metadata_mut().insert(
            "authorization",
            MetadataValue::try_from(format!("Bearer invalid_token_{}", i))?,
        );

        let result = auth_interceptor.clone().authenticate(request).await;

        if result.is_err() {
            failed_attempts += 1;
        }
    }

    println!("  Failed attempts: {} / 10", failed_attempts);
    assert_eq!(
        failed_attempts, 10,
        "All invalid token attempts should fail"
    );

    println!("✓ Multiple failed authentication attempts handled correctly");

    Ok(())
}

#[tokio::test]
async fn test_token_refresh_scenario() -> Result<()> {
    println!("\n=== Test: Token Refresh Scenario ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate initial token
    let (token1, jti1) = generate_test_token(
        "user_refresh",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    // First request with token1
    let mut request1 = Request::new(());
    request1.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token1))?,
    );

    let result1 = auth_interceptor.clone().authenticate(request1).await;
    assert!(result1.is_ok(), "First token should be valid");
    println!("✓ Initial token validated");

    // Revoke first token (simulate user requested refresh)
    let revocation_service = RevocationService::new(REDIS_URL).await?;
    revocation_service
        .revoke_token(&Jti::from_string(jti1), 3600)
        .await?;
    println!("✓ Old token revoked");

    // Generate new token for same user (refresh)
    let (token2, _jti2) = generate_test_token(
        "user_refresh",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    // Request with revoked token should fail
    let mut request2 = Request::new(());
    request2.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token1))?,
    );

    let result2 = auth_interceptor.clone().authenticate(request2).await;
    assert!(result2.is_err(), "Revoked token should fail");
    println!("✓ Revoked token rejected");

    // Request with new token should succeed
    let mut request3 = Request::new(());
    request3.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token2))?,
    );

    let result3 = auth_interceptor.clone().authenticate(request3).await;
    assert!(result3.is_ok(), "New token should be valid");
    println!("✓ New token validated");

    Ok(())
}

#[tokio::test]
async fn test_bearer_token_case_sensitivity() -> Result<()> {
    println!("\n=== Test: Bearer Token Case Sensitivity ===");

    let auth_interceptor = setup_auth_components().await?;

    let (token, _jti) = generate_test_token(
        "user_case_test",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    // Test with lowercase "bearer" (should fail)
    let mut request1 = Request::new(());
    request1.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("bearer {}", token))?,
    );

    let result1 = auth_interceptor.clone().authenticate(request1).await;
    assert!(result1.is_err(), "Lowercase 'bearer' should be rejected");
    println!("✓ Lowercase 'bearer' rejected");

    // Test with correct "Bearer" (should succeed)
    let mut request2 = Request::new(());
    request2.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}", token))?,
    );

    let result2 = auth_interceptor.clone().authenticate(request2).await;
    assert!(result2.is_ok(), "Correct 'Bearer' should succeed");
    println!("✓ Correct 'Bearer' accepted");

    Ok(())
}

#[tokio::test]
async fn test_token_with_whitespace_padding() -> Result<()> {
    println!("\n=== Test: Token with Whitespace Padding ===");

    let auth_interceptor = setup_auth_components().await?;

    let (token, _jti) = generate_test_token(
        "user_whitespace",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    // Test with trailing whitespace
    let mut request1 = Request::new(());
    request1.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer {}  ", token))?,
    );

    let result1 = auth_interceptor.clone().authenticate(request1).await;
    // This might fail due to whitespace in token
    println!(
        "  Trailing whitespace result: {}",
        if result1.is_ok() { "OK" } else { "FAIL" }
    );

    // Test with leading whitespace after Bearer
    let mut request2 = Request::new(());
    request2.metadata_mut().insert(
        "authorization",
        MetadataValue::try_from(format!("Bearer  {}", token))?,
    );

    let result2 = auth_interceptor.clone().authenticate(request2).await;
    println!(
        "  Leading whitespace result: {}",
        if result2.is_ok() { "OK" } else { "FAIL" }
    );

    println!("✓ Whitespace handling tested");

    Ok(())
}

// ============================================================================
// Performance and Stress Edge Cases
// ============================================================================

#[tokio::test]
async fn test_authentication_performance_under_load() -> Result<()> {
    println!("\n=== Test: Authentication Performance Under Load ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate token
    let (token, _jti) = generate_test_token(
        "user_perf",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    // Measure 100 sequential authentications
    let mut latencies = vec![];

    for _ in 0..100 {
        let mut request = Request::new(());
        request.metadata_mut().insert(
            "authorization",
            MetadataValue::try_from(format!("Bearer {}", token))?,
        );

        let start = Instant::now();
        let _ = auth_interceptor.clone().authenticate(request).await?;
        latencies.push(start.elapsed());
    }

    // Calculate percentiles
    latencies.sort();
    let p50 = latencies[49];
    let p95 = latencies[94];
    let p99 = latencies[98];

    println!("\n  Authentication Latency:");
    println!("  ├─ P50:  {:?}", p50);
    println!("  ├─ P95:  {:?}", p95);
    println!("  └─ P99:  {:?}", p99);
    println!("  Target: <10μs");

    if p99 > Duration::from_micros(10) {
        println!("  ⚠ WARNING: P99 latency exceeds 10μs target");
    } else {
        println!("  ✓ Performance target met");
    }

    Ok(())
}

#[tokio::test]
async fn test_concurrent_authentication_requests() -> Result<()> {
    println!("\n=== Test: Concurrent Authentication Requests ===");

    let auth_interceptor = setup_auth_components().await?;

    // Generate token
    let (token, _jti) = generate_test_token(
        "user_concurrent_auth",
        vec!["trader".to_string()],
        vec!["api.access".to_string()],
        3600,
    )?;

    // Spawn 50 concurrent authentication requests
    let mut handles = vec![];

    println!("  Spawning 50 concurrent auth requests...");
    for _ in 0..50 {
        let interceptor = auth_interceptor.clone();
        let token_clone = token.clone();

        let handle = tokio::spawn(async move {
            let mut request = Request::new(());
            request.metadata_mut().insert(
                "authorization",
                MetadataValue::try_from(format!("Bearer {}", token_clone)).unwrap(),
            );

            interceptor.authenticate(request).await
        });

        handles.push(handle);
    }

    // Collect results
    let mut success_count = 0;
    for handle in handles {
        if let Ok(Ok(_)) = handle.await {
            success_count += 1;
        }
    }

    println!("  ✓ {} / 50 concurrent auths succeeded", success_count);
    assert_eq!(
        success_count, 50,
        "All concurrent authentications should succeed"
    );

    Ok(())
}
