#![cfg(feature = "provider-test")]
//! CosmosDB Provider Stress Tests for Duroxide
//!
//! These tests validate the CosmosDB provider under sustained load using the
//! provider stress test infrastructure from the main crate.

use duroxide::provider_stress_tests::parallel_orchestrations::{
    run_parallel_orchestrations_test_with_config, ProviderStressFactory,
};
use duroxide::provider_stress_tests::StressTestConfig;
use duroxide::providers::Provider;
use std::sync::Arc;

mod common;

/// Factory for creating CosmosDB providers for stress testing
struct CosmosDBStressFactory;

#[async_trait::async_trait]
impl ProviderStressFactory for CosmosDBStressFactory {
    async fn create_provider(&self) -> Arc<dyn Provider> {
        let (store, _container) = common::create_cosmos_store().await;
        store
    }
}

#[tokio::test]
#[ignore] // Run with: cargo test --test stress_tests -- --ignored
async fn stress_test_parallel_orchestrations_light() {
    let factory = CosmosDBStressFactory;

    let config = StressTestConfig {
        max_concurrent: 10,
        duration_secs: 10,
        tasks_per_instance: 3,
        activity_delay_ms: 10,
        orch_concurrency: 2,
        worker_concurrency: 2,
        wait_timeout_secs: 120,
    };

    let result = run_parallel_orchestrations_test_with_config(&factory, config)
        .await
        .expect("Stress test failed");

    // Assert quality requirements
    assert_eq!(
        result.success_rate(),
        100.0,
        "Expected 100% success rate, got {:.2}%",
        result.success_rate()
    );
    assert_eq!(
        result.failed_infrastructure, 0,
        "Infrastructure failures detected: {}",
        result.failed_infrastructure
    );
    assert!(
        result.orch_throughput > 1.0,
        "Throughput too low: {:.2} orch/sec",
        result.orch_throughput
    );
}

#[tokio::test]
#[ignore]
async fn stress_test_parallel_orchestrations_standard() {
    let factory = CosmosDBStressFactory;

    let config = StressTestConfig {
        max_concurrent: 20,
        duration_secs: 20,
        tasks_per_instance: 5,
        activity_delay_ms: 20,
        orch_concurrency: 2,
        worker_concurrency: 2,
        wait_timeout_secs: 120,
    };

    let result = run_parallel_orchestrations_test_with_config(&factory, config)
        .await
        .expect("Stress test failed");

    assert_eq!(result.success_rate(), 100.0);
    assert_eq!(result.failed_infrastructure, 0);
}

#[tokio::test]
#[ignore]
async fn stress_test_high_concurrency() {
    let factory = CosmosDBStressFactory;

    let config = StressTestConfig {
        max_concurrent: 50,
        duration_secs: 60,
        tasks_per_instance: 10,
        activity_delay_ms: 20,
        orch_concurrency: 4,
        worker_concurrency: 4,
        wait_timeout_secs: 120,
    };

    let result = run_parallel_orchestrations_test_with_config(&factory, config)
        .await
        .expect("Stress test failed");

    assert_eq!(result.success_rate(), 100.0);
    assert_eq!(result.failed_infrastructure, 0);

    // Validate throughput meets minimum requirements
    assert!(
        result.orch_throughput > 2.0,
        "Throughput below minimum: {:.2} orch/sec",
        result.orch_throughput
    );
}

/// Stress test for CosmosDB rate limiting behavior.
/// CosmosDB doesn't have connection pools like PostgreSQL, but can hit
/// request unit (RU) throttling under high concurrency.
#[tokio::test]
#[ignore]
async fn stress_test_rate_limiting() {
    let factory = CosmosDBStressFactory;

    let config = StressTestConfig {
        max_concurrent: 30,
        duration_secs: 20,
        tasks_per_instance: 5,
        activity_delay_ms: 20,
        orch_concurrency: 4,
        worker_concurrency: 4,
        wait_timeout_secs: 120,
    };

    let result = run_parallel_orchestrations_test_with_config(&factory, config)
        .await
        .expect("Stress test failed");

    // Should still succeed despite potential RU throttling
    assert_eq!(result.success_rate(), 100.0);
}

#[tokio::test]
#[ignore]
async fn stress_test_long_duration_stability() {
    let factory = CosmosDBStressFactory;

    let config = StressTestConfig {
        max_concurrent: 20,
        duration_secs: 600, // 10 minutes (doubled from PG's 5 minutes)
        tasks_per_instance: 5,
        activity_delay_ms: 20,
        orch_concurrency: 2,
        worker_concurrency: 2,
        wait_timeout_secs: 120,
    };

    let result = run_parallel_orchestrations_test_with_config(&factory, config)
        .await
        .expect("Stress test failed");

    assert_eq!(result.success_rate(), 100.0);

    // Validate sustained throughput
    assert!(
        result.orch_throughput > 1.5,
        "Throughput degraded over time: {:.2} orch/sec",
        result.orch_throughput
    );
}
