use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoadTestConfig {
    pub gateway_url: String,
    pub prometheus_url: Option<String>,
    pub auth: AuthConfig,
    pub scenarios: ScenariosConfig,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfig {
    pub jwt_secret: String,
    pub username: String,
    pub user_id: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScenariosConfig {
    pub normal_load: NormalLoadConfig,
    pub spike_load: SpikeLoadConfig,
    pub sustained_load: SustainedLoadConfig,
    pub stress_test: StressTestConfig,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NormalLoadConfig {
    pub num_clients: usize,
    pub duration_secs: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SpikeLoadConfig {
    pub target_clients: usize,
    pub ramp_up_secs: u64,
    pub sustain_secs: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SustainedLoadConfig {
    pub num_clients: usize,
    pub duration_secs: u64,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StressTestConfig {
    pub initial_clients: usize,
    pub increment: usize,
    pub increment_interval_secs: u64,
    pub max_p99_latency_ms: f64,
    pub max_error_rate_pct: f64,
}

impl Default for LoadTestConfig {
    fn default() -> Self {
        Self {
            gateway_url: "http://localhost:50050".to_string(),
            prometheus_url: Some("http://localhost:9090".to_string()),
            auth: AuthConfig::default(),
            scenarios: ScenariosConfig::default(),
        }
    }
}

impl Default for AuthConfig {
    fn default() -> Self {
        Self {
            jwt_secret: "test-secret-key-for-load-testing".to_string(),
            username: "load-test-user".to_string(),
            user_id: "load-test-user-id".to_string(),
        }
    }
}

impl Default for ScenariosConfig {
    fn default() -> Self {
        Self {
            normal_load: NormalLoadConfig {
                num_clients: 1000_usize,
                duration_secs: 60_u64,
            },
            spike_load: SpikeLoadConfig {
                target_clients: 10000_usize,
                ramp_up_secs: 10_u64,
                sustain_secs: 60_u64,
            },
            sustained_load: SustainedLoadConfig {
                num_clients: 100_usize,
                duration_secs: 86400_u64, // 24 hours
            },
            stress_test: StressTestConfig {
                initial_clients: 100_usize,
                increment: 100_usize,
                increment_interval_secs: 60_u64,
                max_p99_latency_ms: 50.0,
                max_error_rate_pct: 5.0,
            },
        }
    }
}
