//! Configuration file parsing utilities

use crate::config::{ProtocolType, ServerConfig, WorkerClass};
use crate::errors::{FalcornError, Result};
use serde::Deserialize;
use std::fs;
use std::path::Path;

/// Raw TOML configuration structure matching file format
#[derive(Debug, Deserialize)]
pub struct TomlConfig {
    #[serde(default)]
    pub server: ServerSection,
    #[serde(default)]
    pub workers: WorkersSection,
    #[serde(default)]
    pub performance: PerformanceSection,
    #[serde(default)]
    pub app: AppSection,
    #[serde(default)]
    pub logging: LoggingSection,
    #[serde(default)]
    pub control: ControlSection,
    #[serde(default)]
    pub ssl: SslSection,
}

#[derive(Debug, Deserialize)]
pub struct ServerSection {
    #[serde(default = "default_host")]
    pub host: String,
    #[serde(default = "default_port")]
    pub port: u16,
    #[serde(default = "default_protocol")]
    pub protocol: String,
    #[serde(default = "default_h2c_enabled")]
    pub h2c_enabled: bool,
    #[serde(default = "default_strict_http")]
    pub strict_http: bool,
    #[serde(default = "default_backlog")]
    pub backlog: u32,
    #[serde(default = "default_worker_mode")]
    pub worker_mode: bool,
    #[serde(default = "default_config_path")]
    pub config_path: Option<String>,
}

impl Default for ServerSection {
    fn default() -> Self {
        Self {
            host: default_host(),
            port: default_port(),
            protocol: default_protocol(),
            h2c_enabled: default_h2c_enabled(),
            strict_http: default_strict_http(),
            backlog: default_backlog(),
            worker_mode: default_worker_mode(),
            config_path: default_config_path(),
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct WorkersSection {
    pub count: Option<usize>,
    #[serde(default = "default_worker_class")]
    pub class: String,
    #[serde(default = "default_timeout")]
    pub timeout: u64,
    pub max_requests: Option<usize>,
    pub max_requests_jitter: Option<usize>,
}

impl Default for WorkersSection {
    fn default() -> Self {
        Self {
            count: None,
            class: default_worker_class(),
            timeout: default_timeout(),
            max_requests: None,
            max_requests_jitter: None,
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct PerformanceSection {
    #[serde(default = "default_buffer_size")]
    pub buffer_size: usize,
    #[serde(default = "default_keepalive")]
    pub keepalive_timeout: u64,
    #[serde(default = "default_max_connections")]
    pub max_connections: usize,
    #[serde(default = "default_sync_handler_threads")]
    pub sync_handler_threads: usize,
    #[serde(default = "default_sync_conn_queue_capacity")]
    pub sync_conn_queue_capacity: usize,
    #[serde(default = "default_async_worker_threads")]
    pub async_worker_threads: usize,
    #[serde(default = "default_async_max_blocking_threads")]
    pub async_max_blocking_threads: usize,
}

impl Default for PerformanceSection {
    fn default() -> Self {
        Self {
            buffer_size: default_buffer_size(),
            keepalive_timeout: default_keepalive(),
            max_connections: default_max_connections(),
            sync_handler_threads: default_sync_handler_threads(),
            sync_conn_queue_capacity: default_sync_conn_queue_capacity(),
            async_worker_threads: default_async_worker_threads(),
            async_max_blocking_threads: default_async_max_blocking_threads(),
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct AppSection {
    #[serde(default = "default_module")]
    pub module: String,
    #[serde(default = "default_callable")]
    pub callable: String,
    #[serde(default)]
    pub pythonpath: Vec<String>,
    #[serde(default = "default_asgi_event_loop")]
    pub asgi_event_loop: String,
    #[serde(default = "default_asgi_event_loop_fallback")]
    pub asgi_event_loop_fallback: bool,
    #[serde(default = "default_asgi_submit_timeout_ms")]
    pub asgi_submit_timeout_ms: u64,
    #[serde(default = "default_asgi_scheduler")]
    pub asgi_scheduler: String,
    #[serde(default = "default_asgi_max_inflight")]
    pub asgi_max_inflight: usize,
    #[serde(default = "default_asgi_send_pool_size")]
    pub asgi_send_pool_size: usize,
}

impl Default for AppSection {
    fn default() -> Self {
        Self {
            module: default_module(),
            callable: default_callable(),
            pythonpath: Vec::new(),
            asgi_event_loop: default_asgi_event_loop(),
            asgi_event_loop_fallback: default_asgi_event_loop_fallback(),
            asgi_submit_timeout_ms: default_asgi_submit_timeout_ms(),
            asgi_scheduler: default_asgi_scheduler(),
            asgi_max_inflight: default_asgi_max_inflight(),
            asgi_send_pool_size: default_asgi_send_pool_size(),
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct LoggingSection {
    #[serde(default = "default_log_stdout")]
    pub log_stdout: bool,
    #[serde(default = "default_log_level")]
    pub level: String,
    #[serde(default = "default_log_format")]
    pub format: String,
    pub access_log: Option<String>,
    pub error_log: Option<String>,
    pub plugin_socket: Option<String>,
    pub plugin_auth_token: Option<String>,
    #[serde(default = "default_plugin_drop_policy")]
    pub plugin_drop_policy: String,
    #[serde(default = "default_plugin_max_lagged_events")]
    pub plugin_max_lagged_events: usize,
    #[serde(default = "default_plugin_write_timeout_ms")]
    pub plugin_write_timeout_ms: u64,
    #[serde(default = "default_plugin_bus_capacity")]
    pub plugin_bus_capacity: usize,
    #[serde(default = "default_plugin_max_clients")]
    pub plugin_max_clients: usize,
    #[serde(default = "default_plugin_subscribe_timeout_ms")]
    pub plugin_subscribe_timeout_ms: u64,
    #[serde(default = "default_plugin_auth_fail_window_secs")]
    pub plugin_auth_fail_window_secs: u64,
    #[serde(default = "default_plugin_auth_fail_max_attempts")]
    pub plugin_auth_fail_max_attempts: usize,
    #[serde(default = "default_plugin_acl_mode")]
    pub plugin_acl_mode: String,
    #[serde(default = "default_plugin_socket_mode")]
    pub plugin_socket_mode: u32,
    #[serde(default = "default_metrics_interval_ms")]
    pub metrics_interval_ms: u64,
    #[serde(default = "default_metrics_workers_enabled")]
    pub metrics_workers_enabled: bool,
    #[serde(default = "default_metrics_os_enabled")]
    pub metrics_os_enabled: bool,
    #[serde(default = "default_metrics_percentiles_enabled")]
    pub metrics_percentiles_enabled: bool,
    #[serde(default = "default_metrics_top_errors_limit")]
    pub metrics_top_errors_limit: usize,
}

impl Default for LoggingSection {
    fn default() -> Self {
        Self {
            log_stdout: default_log_stdout(),
            level: default_log_level(),
            format: default_log_format(),
            access_log: None,
            error_log: None,
            plugin_socket: None,
            plugin_auth_token: None,
            plugin_drop_policy: default_plugin_drop_policy(),
            plugin_max_lagged_events: default_plugin_max_lagged_events(),
            plugin_write_timeout_ms: default_plugin_write_timeout_ms(),
            plugin_bus_capacity: default_plugin_bus_capacity(),
            plugin_max_clients: default_plugin_max_clients(),
            plugin_subscribe_timeout_ms: default_plugin_subscribe_timeout_ms(),
            plugin_auth_fail_window_secs: default_plugin_auth_fail_window_secs(),
            plugin_auth_fail_max_attempts: default_plugin_auth_fail_max_attempts(),
            plugin_acl_mode: default_plugin_acl_mode(),
            plugin_socket_mode: default_plugin_socket_mode(),
            metrics_interval_ms: default_metrics_interval_ms(),
            metrics_workers_enabled: default_metrics_workers_enabled(),
            metrics_os_enabled: default_metrics_os_enabled(),
            metrics_percentiles_enabled: default_metrics_percentiles_enabled(),
            metrics_top_errors_limit: default_metrics_top_errors_limit(),
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct ControlSection {
    #[serde(default = "default_control_socket")]
    pub socket: Option<String>,
    pub auth_token: Option<String>,
    #[serde(default = "default_control_acl_mode")]
    pub acl_mode: String,
    #[serde(default = "default_control_socket_mode")]
    pub socket_mode: u32,
}

impl Default for ControlSection {
    fn default() -> Self {
        Self {
            socket: default_control_socket(),
            auth_token: None,
            acl_mode: default_control_acl_mode(),
            socket_mode: default_control_socket_mode(),
        }
    }
}

#[derive(Debug, Deserialize)]
pub struct SslSection {
    #[serde(default = "default_ssl_enabled")]
    pub enabled: bool,
    pub certfile: Option<String>,
    pub keyfile: Option<String>,
}

impl Default for SslSection {
    fn default() -> Self {
        Self {
            enabled: default_ssl_enabled(),
            certfile: None,
            keyfile: None,
        }
    }
}

// Default value functions
fn default_host() -> String {
    "127.0.0.1".to_string()
}
fn default_port() -> u16 {
    8000
}
fn default_protocol() -> String {
    "wsgi".to_string()
}
fn default_h2c_enabled() -> bool {
    false
}
fn default_strict_http() -> bool {
    false
}
fn default_backlog() -> u32 {
    8192
}
fn default_worker_class() -> String {
    "sync".to_string()
}
fn default_worker_mode() -> bool {
    false
}
fn default_log_stdout() -> bool {
    false
}
fn default_ssl_enabled() -> bool {
    false
}
fn default_timeout() -> u64 {
    30
}
fn default_buffer_size() -> usize {
    4096
}
fn default_keepalive() -> u64 {
    5
}
fn default_max_connections() -> usize {
    2048
}
fn default_sync_handler_threads() -> usize {
    num_cpus::get().clamp(2, 8)
}
fn default_sync_conn_queue_capacity() -> usize {
    4096
}
fn default_async_worker_threads() -> usize {
    4
}
fn default_async_max_blocking_threads() -> usize {
    100
}
fn default_module() -> String {
    "app".to_string()
}
fn default_callable() -> String {
    "application".to_string()
}
fn default_asgi_event_loop() -> String {
    "asyncio".to_string()
}
fn default_asgi_event_loop_fallback() -> bool {
    true
}
fn default_asgi_submit_timeout_ms() -> u64 {
    30_000
}
fn default_asgi_scheduler() -> String {
    "task".to_string()
}
fn default_asgi_max_inflight() -> usize {
    256
}
fn default_asgi_send_pool_size() -> usize {
    4096
}
fn default_log_level() -> String {
    "INFO".to_string()
}
fn default_log_format() -> String {
    r#"%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s"#.to_string()
}
fn default_plugin_drop_policy() -> String {
    "drop_oldest".to_string()
}
fn default_plugin_max_lagged_events() -> usize {
    2048
}
fn default_plugin_write_timeout_ms() -> u64 {
    500
}
fn default_plugin_bus_capacity() -> usize {
    8192
}
fn default_plugin_max_clients() -> usize {
    1024
}
fn default_plugin_subscribe_timeout_ms() -> u64 {
    5000
}
fn default_plugin_auth_fail_window_secs() -> u64 {
    60
}
fn default_plugin_auth_fail_max_attempts() -> usize {
    10
}
fn default_plugin_acl_mode() -> String {
    "same_user".to_string()
}
fn default_plugin_socket_mode() -> u32 {
    0o660
}

fn default_metrics_interval_ms() -> u64 {
    5000
}

fn default_metrics_workers_enabled() -> bool {
    true
}

fn default_metrics_os_enabled() -> bool {
    false
}

fn default_metrics_percentiles_enabled() -> bool {
    false
}

fn default_metrics_top_errors_limit() -> usize {
    5
}
fn default_control_socket() -> Option<String> {
    Some(crate::control::ipc::DEFAULT_CONTROL_SOCKET.to_string())
}
fn default_control_acl_mode() -> String {
    "same_user".to_string()
}
fn default_control_socket_mode() -> u32 {
    0o660
}
fn default_config_path() -> Option<String> {
    None
}

impl TomlConfig {
    /// Parse TOML configuration from file
    pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self> {
        let content = fs::read_to_string(path.as_ref()).map_err(|e| {
            FalcornError::config(format!(
                "Failed to read config file '{}': {}",
                path.as_ref().display(),
                e
            ))
        })?;

        Self::from_str(&content)
    }

    /// Parse TOML configuration from string
    pub fn from_str(content: &str) -> Result<Self> {
        toml::from_str(content)
            .map_err(|e| FalcornError::config(format!("Failed to parse TOML: {}", e)))
    }

    /// Convert to ServerConfig
    pub fn into_server_config(self) -> Result<ServerConfig> {
        let worker_class = WorkerClass::from_str(&self.workers.class)?;
        let protocol = ProtocolType::from_str(&self.server.protocol)?;

        Ok(ServerConfig {
            host: self.server.host,
            port: self.server.port,
            protocol,
            h2c_enabled: self.server.h2c_enabled,
            strict_http: self.server.strict_http,
            backlog: self.server.backlog,
            workers: self.workers.count,
            worker_class,
            worker_timeout: self.workers.timeout,
            worker_mode: self.server.worker_mode,
            max_requests: self.workers.max_requests,
            max_requests_jitter: self.workers.max_requests_jitter,
            buffer_size: self.performance.buffer_size,
            keepalive_timeout: self.performance.keepalive_timeout,
            max_connections: self.performance.max_connections,
            sync_handler_threads: self.performance.sync_handler_threads,
            sync_conn_queue_capacity: self.performance.sync_conn_queue_capacity,
            async_worker_threads: self.performance.async_worker_threads,
            async_max_blocking_threads: self.performance.async_max_blocking_threads,
            app_module: self.app.module,
            app_callable: self.app.callable,
            pythonpath: self.app.pythonpath,
            asgi_event_loop: self.app.asgi_event_loop,
            asgi_event_loop_fallback: self.app.asgi_event_loop_fallback,
            asgi_submit_timeout_ms: self.app.asgi_submit_timeout_ms,
            asgi_scheduler: self.app.asgi_scheduler,
            asgi_max_inflight: self.app.asgi_max_inflight,
            asgi_send_pool_size: self.app.asgi_send_pool_size,
            log_stdout: self.logging.log_stdout,
            log_level: self.logging.level,
            access_log_format: self.logging.format,
            access_log: normalize_optional_non_empty(self.logging.access_log),
            error_log: normalize_optional_non_empty(self.logging.error_log),
            plugin_socket: normalize_optional_non_empty(self.logging.plugin_socket),
            plugin_auth_token: normalize_optional_non_empty(self.logging.plugin_auth_token),
            plugin_drop_policy: self.logging.plugin_drop_policy,
            plugin_max_lagged_events: self.logging.plugin_max_lagged_events,
            plugin_write_timeout_ms: self.logging.plugin_write_timeout_ms,
            plugin_bus_capacity: self.logging.plugin_bus_capacity,
            plugin_max_clients: self.logging.plugin_max_clients,
            plugin_subscribe_timeout_ms: self.logging.plugin_subscribe_timeout_ms,
            plugin_auth_fail_window_secs: self.logging.plugin_auth_fail_window_secs,
            plugin_auth_fail_max_attempts: self.logging.plugin_auth_fail_max_attempts,
            plugin_acl_mode: self.logging.plugin_acl_mode,
            plugin_socket_mode: self.logging.plugin_socket_mode,
            metrics_interval_ms: self.logging.metrics_interval_ms,
            metrics_workers_enabled: self.logging.metrics_workers_enabled,
            metrics_os_enabled: self.logging.metrics_os_enabled,
            metrics_percentiles_enabled: self.logging.metrics_percentiles_enabled,
            metrics_top_errors_limit: self.logging.metrics_top_errors_limit,
            control_socket: normalize_optional_non_empty(self.control.socket),
            control_auth_token: normalize_optional_non_empty(self.control.auth_token),
            control_acl_mode: self.control.acl_mode,
            control_socket_mode: self.control.socket_mode,
            config_path: self.server.config_path,
            ssl_enabled: self.ssl.enabled,
            ssl_certfile: self.ssl.certfile,
            ssl_keyfile: self.ssl.keyfile,
        })
    }
}

/// Configuration parser
pub struct ConfigParser;

impl ConfigParser {
    /// Parse configuration from TOML file
    pub fn parse_file<P: AsRef<Path>>(path: P) -> Result<ServerConfig> {
        let toml_config = TomlConfig::from_file(&path)?;
        let mut config = toml_config.into_server_config()?;
        config.config_path = Some(path.as_ref().to_string_lossy().to_string());
        Ok(config)
    }

    /// Parse configuration from TOML string
    pub fn parse_str(content: &str) -> Result<ServerConfig> {
        let toml_config = TomlConfig::from_str(content)?;
        toml_config.into_server_config()
    }

    /// Merge configuration with CLI overrides
    pub fn merge_with_cli(
        mut config: ServerConfig,
        cli_overrides: CliOverrides,
    ) -> Result<ServerConfig> {
        if let Some(app_module) = cli_overrides.app_module {
            config.app_module = app_module;
        }
        if let Some(app_callable) = cli_overrides.app_callable {
            config.app_callable = app_callable;
        }
        if let Some(host) = cli_overrides.host {
            config.host = host;
        }
        if let Some(port) = cli_overrides.port {
            config.port = port;
        }
        if let Some(backlog) = cli_overrides.backlog {
            config.backlog = backlog;
        }
        if let Some(workers) = cli_overrides.workers {
            config.workers = Some(workers);
        }
        if let Some(protocol) = cli_overrides.protocol {
            config.protocol = ProtocolType::from_str(&protocol)?;
        }
        if let Some(worker_class) = cli_overrides.worker_class {
            config.worker_class = WorkerClass::from_str(&worker_class)?;
        }
        if let Some(timeout) = cli_overrides.timeout {
            config.worker_timeout = timeout;
        }
        if let Some(worker_mode) = cli_overrides.worker_mode {
            config.worker_mode = worker_mode;
        }
        if let Some(h2c_enabled) = cli_overrides.h2c_enabled {
            config.h2c_enabled = h2c_enabled;
        }
        if let Some(strict_http) = cli_overrides.strict_http {
            config.strict_http = strict_http;
        }
        if let Some(max_requests) = cli_overrides.max_requests {
            config.max_requests = Some(max_requests);
        }
        if let Some(max_requests_jitter) = cli_overrides.max_requests_jitter {
            config.max_requests_jitter = Some(max_requests_jitter);
        }
        if let Some(buffer_size) = cli_overrides.buffer_size {
            config.buffer_size = buffer_size;
        }
        if let Some(keepalive_timeout) = cli_overrides.keepalive_timeout {
            config.keepalive_timeout = keepalive_timeout;
        }
        if let Some(max_connections) = cli_overrides.max_connections {
            config.max_connections = max_connections;
        }
        if let Some(sync_handler_threads) = cli_overrides.sync_handler_threads {
            config.sync_handler_threads = sync_handler_threads;
        }
        if let Some(sync_conn_queue_capacity) = cli_overrides.sync_conn_queue_capacity {
            config.sync_conn_queue_capacity = sync_conn_queue_capacity;
        }
        if let Some(async_worker_threads) = cli_overrides.async_worker_threads {
            config.async_worker_threads = async_worker_threads;
        }
        if let Some(async_max_blocking_threads) = cli_overrides.async_max_blocking_threads {
            config.async_max_blocking_threads = async_max_blocking_threads;
        }
        if let Some(log_level) = cli_overrides.log_level {
            config.log_level = log_level;
        }
        if let Some(log_stdout) = cli_overrides.log_stdout {
            config.log_stdout = log_stdout;
        }
        if let Some(access_log_format) = cli_overrides.access_log_format {
            config.access_log_format = access_log_format;
        }
        if let Some(access_log) = cli_overrides.access_log {
            config.access_log = normalize_optional_non_empty(Some(access_log));
        }
        if let Some(error_log) = cli_overrides.error_log {
            config.error_log = normalize_optional_non_empty(Some(error_log));
        }
        if let Some(plugin_socket) = cli_overrides.plugin_socket {
            config.plugin_socket = normalize_optional_non_empty(Some(plugin_socket));
        }
        if let Some(plugin_auth_token) = cli_overrides.plugin_auth_token {
            config.plugin_auth_token = normalize_optional_non_empty(Some(plugin_auth_token));
        }
        if let Some(plugin_drop_policy) = cli_overrides.plugin_drop_policy {
            config.plugin_drop_policy = plugin_drop_policy;
        }
        if let Some(plugin_max_lagged_events) = cli_overrides.plugin_max_lagged_events {
            config.plugin_max_lagged_events = plugin_max_lagged_events;
        }
        if let Some(plugin_write_timeout_ms) = cli_overrides.plugin_write_timeout_ms {
            config.plugin_write_timeout_ms = plugin_write_timeout_ms;
        }
        if let Some(plugin_bus_capacity) = cli_overrides.plugin_bus_capacity {
            config.plugin_bus_capacity = plugin_bus_capacity;
        }
        if let Some(plugin_max_clients) = cli_overrides.plugin_max_clients {
            config.plugin_max_clients = plugin_max_clients;
        }
        if let Some(plugin_subscribe_timeout_ms) = cli_overrides.plugin_subscribe_timeout_ms {
            config.plugin_subscribe_timeout_ms = plugin_subscribe_timeout_ms;
        }
        if let Some(plugin_auth_fail_window_secs) = cli_overrides.plugin_auth_fail_window_secs {
            config.plugin_auth_fail_window_secs = plugin_auth_fail_window_secs;
        }
        if let Some(plugin_auth_fail_max_attempts) = cli_overrides.plugin_auth_fail_max_attempts {
            config.plugin_auth_fail_max_attempts = plugin_auth_fail_max_attempts;
        }
        if let Some(plugin_acl_mode) = cli_overrides.plugin_acl_mode {
            config.plugin_acl_mode = plugin_acl_mode;
        }
        if let Some(plugin_socket_mode) = cli_overrides.plugin_socket_mode {
            config.plugin_socket_mode = plugin_socket_mode;
        }
        if let Some(metrics_interval_ms) = cli_overrides.metrics_interval_ms {
            config.metrics_interval_ms = metrics_interval_ms;
        }
        if let Some(metrics_workers_enabled) = cli_overrides.metrics_workers_enabled {
            config.metrics_workers_enabled = metrics_workers_enabled;
        }
        if let Some(metrics_os_enabled) = cli_overrides.metrics_os_enabled {
            config.metrics_os_enabled = metrics_os_enabled;
        }
        if let Some(metrics_percentiles_enabled) = cli_overrides.metrics_percentiles_enabled {
            config.metrics_percentiles_enabled = metrics_percentiles_enabled;
        }
        if let Some(metrics_top_errors_limit) = cli_overrides.metrics_top_errors_limit {
            config.metrics_top_errors_limit = metrics_top_errors_limit;
        }
        if let Some(control_socket) = cli_overrides.control_socket {
            config.control_socket = normalize_optional_non_empty(Some(control_socket));
        }
        if let Some(control_auth_token) = cli_overrides.control_auth_token {
            config.control_auth_token = normalize_optional_non_empty(Some(control_auth_token));
        }
        if let Some(control_acl_mode) = cli_overrides.control_acl_mode {
            config.control_acl_mode = control_acl_mode;
        }
        if let Some(control_socket_mode) = cli_overrides.control_socket_mode {
            config.control_socket_mode = control_socket_mode;
        }
        if let Some(ssl_enabled) = cli_overrides.ssl_enabled {
            config.ssl_enabled = ssl_enabled;
        }
        if let Some(ssl_certfile) = cli_overrides.ssl_certfile {
            config.ssl_certfile = Some(ssl_certfile);
        }
        if let Some(ssl_keyfile) = cli_overrides.ssl_keyfile {
            config.ssl_keyfile = Some(ssl_keyfile);
        }
        if let Some(pythonpath) = cli_overrides.pythonpath {
            if !pythonpath.is_empty() {
                config.pythonpath = pythonpath;
            }
        }
        if let Some(asgi_event_loop) = cli_overrides.asgi_event_loop {
            config.asgi_event_loop = asgi_event_loop;
        }
        if let Some(asgi_event_loop_fallback) = cli_overrides.asgi_event_loop_fallback {
            config.asgi_event_loop_fallback = asgi_event_loop_fallback;
        }
        if let Some(asgi_submit_timeout_ms) = cli_overrides.asgi_submit_timeout_ms {
            config.asgi_submit_timeout_ms = asgi_submit_timeout_ms;
        }
        if let Some(asgi_scheduler) = cli_overrides.asgi_scheduler {
            config.asgi_scheduler = asgi_scheduler;
        }
        if let Some(asgi_max_inflight) = cli_overrides.asgi_max_inflight {
            config.asgi_max_inflight = asgi_max_inflight;
        }
        if let Some(asgi_send_pool_size) = cli_overrides.asgi_send_pool_size {
            config.asgi_send_pool_size = asgi_send_pool_size;
        }

        Ok(config)
    }

    /// Parse environment variables
    pub fn parse_env_vars(mut config: ServerConfig) -> ServerConfig {
        use std::env;

        if let Ok(host) = env::var("FALCORN_HOST") {
            config.host = host;
        }
        if let Ok(port) = env::var("FALCORN_PORT") {
            if let Ok(p) = port.parse() {
                config.port = p;
            }
        }
        if let Ok(h2c_enabled) = env::var("FALCORN_H2C_ENABLED") {
            let value = h2c_enabled.to_lowercase();
            config.h2c_enabled = matches!(value.as_str(), "1" | "true" | "yes" | "on");
        }
        if let Ok(strict_http) = env::var("FALCORN_STRICT_HTTP") {
            let value = strict_http.to_lowercase();
            config.strict_http = matches!(value.as_str(), "1" | "true" | "yes" | "on");
        }
        if let Ok(workers) = env::var("FALCORN_WORKERS") {
            if let Ok(w) = workers.parse() {
                config.workers = Some(w);
            }
        }
        if let Ok(class) = env::var("FALCORN_WORKER_CLASS") {
            if let Ok(wc) = WorkerClass::from_str(&class) {
                config.worker_class = wc;
            }
        }
        if let Ok(level) = env::var("FALCORN_LOG_LEVEL") {
            config.log_level = level;
        }
        if let Ok(loop_backend) = env::var("FALCORN_ASGI_EVENT_LOOP")
            && !loop_backend.trim().is_empty()
        {
            config.asgi_event_loop = loop_backend;
        }
        if let Ok(loop_fallback) = env::var("FALCORN_ASGI_EVENT_LOOP_FALLBACK") {
            let value = loop_fallback.to_lowercase();
            config.asgi_event_loop_fallback = matches!(value.as_str(), "1" | "true" | "yes" | "on");
        }
        if let Ok(submit_timeout_ms) = env::var("FALCORN_ASGI_SUBMIT_TIMEOUT_MS")
            && let Ok(v) = submit_timeout_ms.parse()
        {
            config.asgi_submit_timeout_ms = v;
        }
        if let Ok(asgi_scheduler) = env::var("FALCORN_ASGI_SCHEDULER")
            && !asgi_scheduler.trim().is_empty()
        {
            config.asgi_scheduler = asgi_scheduler;
        }
        if let Ok(max_inflight) = env::var("FALCORN_ASGI_MAX_INFLIGHT")
            && let Ok(v) = max_inflight.parse()
        {
            config.asgi_max_inflight = v;
        }
        if let Ok(send_pool_size) = env::var("FALCORN_ASGI_SEND_POOL_SIZE")
            && let Ok(v) = send_pool_size.parse()
        {
            config.asgi_send_pool_size = v;
        }
        if let Ok(plugin_socket) = env::var("FALCORN_PLUGIN_SOCKET")
            && !plugin_socket.trim().is_empty()
        {
            config.plugin_socket = Some(plugin_socket);
        }
        if let Ok(plugin_auth_token) = env::var("FALCORN_PLUGIN_AUTH_TOKEN")
            && !plugin_auth_token.trim().is_empty()
        {
            config.plugin_auth_token = Some(plugin_auth_token);
        }
        if let Ok(policy) = env::var("FALCORN_PLUGIN_DROP_POLICY")
            && !policy.trim().is_empty()
        {
            config.plugin_drop_policy = policy;
        }
        if let Ok(max_lagged) = env::var("FALCORN_PLUGIN_MAX_LAGGED_EVENTS")
            && let Ok(v) = max_lagged.parse()
        {
            config.plugin_max_lagged_events = v;
        }
        if let Ok(write_timeout_ms) = env::var("FALCORN_PLUGIN_WRITE_TIMEOUT_MS")
            && let Ok(v) = write_timeout_ms.parse()
        {
            config.plugin_write_timeout_ms = v;
        }
        if let Ok(bus_capacity) = env::var("FALCORN_PLUGIN_BUS_CAPACITY")
            && let Ok(v) = bus_capacity.parse()
        {
            config.plugin_bus_capacity = v;
        }
        if let Ok(max_clients) = env::var("FALCORN_PLUGIN_MAX_CLIENTS")
            && let Ok(v) = max_clients.parse()
        {
            config.plugin_max_clients = v;
        }
        if let Ok(subscribe_timeout_ms) = env::var("FALCORN_PLUGIN_SUBSCRIBE_TIMEOUT_MS")
            && let Ok(v) = subscribe_timeout_ms.parse()
        {
            config.plugin_subscribe_timeout_ms = v;
        }
        if let Ok(auth_fail_window_secs) = env::var("FALCORN_PLUGIN_AUTH_FAIL_WINDOW_SECS")
            && let Ok(v) = auth_fail_window_secs.parse()
        {
            config.plugin_auth_fail_window_secs = v;
        }
        if let Ok(auth_fail_max_attempts) = env::var("FALCORN_PLUGIN_AUTH_FAIL_MAX_ATTEMPTS")
            && let Ok(v) = auth_fail_max_attempts.parse()
        {
            config.plugin_auth_fail_max_attempts = v;
        }
        if let Ok(mode) = env::var("FALCORN_PLUGIN_ACL_MODE")
            && !mode.trim().is_empty()
        {
            config.plugin_acl_mode = mode;
        }
        if let Ok(socket_mode) = env::var("FALCORN_PLUGIN_SOCKET_MODE")
            && let Ok(v) = u32::from_str_radix(socket_mode.trim_start_matches("0o"), 8)
        {
            config.plugin_socket_mode = v;
        }
        if let Ok(interval_ms) = env::var("FALCORN_METRICS_INTERVAL_MS")
            && let Ok(v) = interval_ms.parse()
        {
            config.metrics_interval_ms = v;
        }
        if let Ok(enabled) = env::var("FALCORN_METRICS_WORKERS_ENABLED") {
            let value = enabled.to_lowercase();
            config.metrics_workers_enabled = matches!(value.as_str(), "1" | "true" | "yes" | "on");
        }
        if let Ok(enabled) = env::var("FALCORN_METRICS_OS_ENABLED") {
            let value = enabled.to_lowercase();
            config.metrics_os_enabled = matches!(value.as_str(), "1" | "true" | "yes" | "on");
        }
        if let Ok(enabled) = env::var("FALCORN_METRICS_PERCENTILES_ENABLED") {
            let value = enabled.to_lowercase();
            config.metrics_percentiles_enabled =
                matches!(value.as_str(), "1" | "true" | "yes" | "on");
        }
        if let Ok(limit) = env::var("FALCORN_METRICS_TOP_ERRORS_LIMIT")
            && let Ok(v) = limit.parse()
        {
            config.metrics_top_errors_limit = v;
        }
        if let Ok(control_socket) = env::var("FALCORN_CONTROL_SOCKET")
            && !control_socket.trim().is_empty()
        {
            config.control_socket = Some(control_socket);
        }
        if let Ok(control_auth_token) = env::var("FALCORN_CONTROL_AUTH_TOKEN")
            && !control_auth_token.trim().is_empty()
        {
            config.control_auth_token = Some(control_auth_token);
        }
        if let Ok(mode) = env::var("FALCORN_CONTROL_ACL_MODE")
            && !mode.trim().is_empty()
        {
            config.control_acl_mode = mode;
        }
        if let Ok(socket_mode) = env::var("FALCORN_CONTROL_SOCKET_MODE")
            && let Ok(v) = u32::from_str_radix(socket_mode.trim_start_matches("0o"), 8)
        {
            config.control_socket_mode = v;
        }

        config
    }
}

fn normalize_optional_non_empty(value: Option<String>) -> Option<String> {
    value.and_then(|s| {
        let trimmed = s.trim();
        if trimmed.is_empty() {
            None
        } else {
            Some(trimmed.to_string())
        }
    })
}

/// CLI override options
#[derive(Debug, Default)]
pub struct CliOverrides {
    pub app_module: Option<String>,
    pub app_callable: Option<String>,
    pub host: Option<String>,
    pub port: Option<u16>,
    pub backlog: Option<u32>,
    pub workers: Option<usize>,
    pub protocol: Option<String>,
    pub worker_class: Option<String>,
    pub timeout: Option<u64>,
    pub worker_mode: Option<bool>,
    pub h2c_enabled: Option<bool>,
    pub strict_http: Option<bool>,
    pub max_requests: Option<usize>,
    pub max_requests_jitter: Option<usize>,
    pub buffer_size: Option<usize>,
    pub keepalive_timeout: Option<u64>,
    pub max_connections: Option<usize>,
    pub sync_handler_threads: Option<usize>,
    pub sync_conn_queue_capacity: Option<usize>,
    pub async_worker_threads: Option<usize>,
    pub async_max_blocking_threads: Option<usize>,
    pub log_stdout: Option<bool>,
    pub log_level: Option<String>,
    pub access_log_format: Option<String>,
    pub access_log: Option<String>,
    pub error_log: Option<String>,
    pub plugin_socket: Option<String>,
    pub plugin_auth_token: Option<String>,
    pub plugin_drop_policy: Option<String>,
    pub plugin_max_lagged_events: Option<usize>,
    pub plugin_write_timeout_ms: Option<u64>,
    pub plugin_bus_capacity: Option<usize>,
    pub plugin_max_clients: Option<usize>,
    pub plugin_subscribe_timeout_ms: Option<u64>,
    pub plugin_auth_fail_window_secs: Option<u64>,
    pub plugin_auth_fail_max_attempts: Option<usize>,
    pub plugin_acl_mode: Option<String>,
    pub plugin_socket_mode: Option<u32>,
    pub metrics_interval_ms: Option<u64>,
    pub metrics_workers_enabled: Option<bool>,
    pub metrics_os_enabled: Option<bool>,
    pub metrics_percentiles_enabled: Option<bool>,
    pub metrics_top_errors_limit: Option<usize>,
    pub control_socket: Option<String>,
    pub control_auth_token: Option<String>,
    pub control_acl_mode: Option<String>,
    pub control_socket_mode: Option<u32>,
    pub ssl_enabled: Option<bool>,
    pub ssl_certfile: Option<String>,
    pub ssl_keyfile: Option<String>,
    pub pythonpath: Option<Vec<String>>,
    pub asgi_event_loop: Option<String>,
    pub asgi_event_loop_fallback: Option<bool>,
    pub asgi_submit_timeout_ms: Option<u64>,
    pub asgi_scheduler: Option<String>,
    pub asgi_max_inflight: Option<usize>,
    pub asgi_send_pool_size: Option<usize>,
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_parse_toml() {
        let toml = r#"
            [server]
            host = "0.0.0.0"
            port = 8080

            [workers]
            count = 8
            class = "async"

            [app]
            module = "myapp"
            callable = "app"
        "#;

        let config = ConfigParser::parse_str(toml).unwrap();
        assert_eq!(config.host, "0.0.0.0");
        assert_eq!(config.port, 8080);
        assert_eq!(config.workers, Some(8));
        assert_eq!(config.worker_class, WorkerClass::Async);
    }

    #[test]
    fn test_defaults() {
        let toml = r#"
            [app]
            module = "test"
            callable = "app"
        "#;

        let config = ConfigParser::parse_str(toml).unwrap();
        assert_eq!(config.host, "127.0.0.1");
        assert_eq!(config.port, 8000);
        assert_eq!(config.worker_class, WorkerClass::Sync);
        assert!(!config.h2c_enabled);
    }

    #[test]
    fn test_parse_h2c_enabled() {
        let toml = r#"
            [server]
            host = "0.0.0.0"
            h2c_enabled = true

            [workers]
            class = "async"

            [app]
            module = "test"
            callable = "app"
        "#;

        let config = ConfigParser::parse_str(toml).unwrap();
        assert!(config.h2c_enabled);
    }
}
