//! Default values for configuration fields
//!
//! This module centralizes all default value functions used in serde deserialization.

use super::types::CompressionCodec;
use crate::types::{CacheCapacity, MaxConnections, MaxErrors};
use std::path::PathBuf;
use std::time::Duration;

/// Default maximum connections per server
///
/// # Panics
/// Panics only if the hard-coded non-zero default becomes invalid.
#[inline]
#[must_use]
pub fn max_connections() -> MaxConnections {
    MaxConnections::try_new(10).expect("10 is non-zero")
}

/// Default health check interval
#[inline]
#[must_use]
pub const fn health_check_interval() -> Duration {
    Duration::from_secs(30)
}

/// Default health check timeout
#[inline]
#[must_use]
pub const fn health_check_timeout() -> Duration {
    Duration::from_secs(5)
}

/// Default unhealthy threshold
///
/// # Panics
/// Panics only if the hard-coded non-zero default becomes invalid.
#[inline]
#[must_use]
pub fn unhealthy_threshold() -> MaxErrors {
    MaxErrors::try_new(3).expect("3 is non-zero")
}

/// Default cache max capacity in bytes (memory tier)
///
/// # Panics
/// Panics only if the hard-coded non-zero default becomes invalid.
#[inline]
#[must_use]
pub fn cache_max_capacity() -> CacheCapacity {
    // 64 MB default (good for availability-only mode)
    CacheCapacity::try_new(64 * 1024 * 1024).expect("64MB is non-zero")
}

/// Default cache TTL (1 hour)
#[inline]
#[must_use]
pub const fn cache_ttl() -> Duration {
    crate::constants::duration_polyfill::from_hours(1)
}

/// Default for caching article bodies in explicit `[cache]` sections.
///
/// Availability-only mode is the default; set `store_article_bodies = true`
/// explicitly when you want full body caching.
#[inline]
pub const fn cache_articles() -> bool {
    false
}

/// Default for adaptive availability prechecking (false = disabled)
#[inline]
pub const fn adaptive_precheck() -> bool {
    false
}

/// Default socket receive buffer size
#[inline]
#[must_use]
pub const fn socket_recv_buffer_size() -> usize {
    crate::constants::socket::HIGH_THROUGHPUT_RECV_BUFFER
}

/// Default socket send buffer size
#[inline]
#[must_use]
pub const fn socket_send_buffer_size() -> usize {
    crate::constants::socket::HIGH_THROUGHPUT_SEND_BUFFER
}

/// Default size of each pooled I/O buffer
#[inline]
#[must_use]
pub const fn buffer_pool_size() -> usize {
    crate::constants::buffer::POOL
}

/// Default number of buffers in the main buffer pool
/// Sized for ~100 concurrent connections with single buffer per connection
/// Total memory: 100 × 1MiB = 100MiB
#[inline]
#[must_use]
pub const fn buffer_pool_count() -> usize {
    crate::constants::buffer::POOL_COUNT
}

/// Default size of each capture buffer
#[inline]
#[must_use]
pub const fn capture_pool_size() -> usize {
    crate::constants::buffer::CAPTURE
}

/// Default number of buffers in the capture pool for caching
/// Sized for 16 concurrent caching operations
/// Total memory: 16 × 1MiB = 16MiB
#[inline]
#[must_use]
pub const fn capture_pool_count() -> usize {
    crate::constants::buffer::CAPTURE_COUNT
}

/// Default for TLS certificate verification (true for security)
#[inline]
#[must_use]
pub const fn tls_verify_cert() -> bool {
    true
}

/// Default maximum number of connections to check per health check cycle
#[inline]
#[must_use]
pub const fn health_check_max_per_cycle() -> usize {
    use crate::constants::pool::MAX_CONNECTIONS_PER_HEALTH_CHECK_CYCLE;
    MAX_CONNECTIONS_PER_HEALTH_CHECK_CYCLE
}

/// Default timeout when acquiring a connection for health checking
#[inline]
#[must_use]
pub const fn health_check_pool_timeout() -> Duration {
    use crate::constants::pool::HEALTH_CHECK_POOL_TIMEOUT_MS;
    Duration::from_millis(HEALTH_CHECK_POOL_TIMEOUT_MS)
}

// Disk cache defaults (for hybrid-cache feature)

/// Default disk cache path
#[inline]
#[must_use]
pub fn disk_cache_path() -> PathBuf {
    PathBuf::from("/var/cache/nntp-proxy")
}

/// Default disk cache capacity (10 GB)
///
/// # Panics
/// Panics only if the hard-coded non-zero default becomes invalid.
#[inline]
#[must_use]
pub fn disk_cache_capacity() -> CacheCapacity {
    CacheCapacity::try_new(10 * 1024 * 1024 * 1024).expect("10GB is non-zero")
}

/// Default disk cache compression codec (LZ4 = fast, ~60% reduction)
#[inline]
#[must_use]
pub const fn disk_cache_compression_codec() -> CompressionCodec {
    CompressionCodec::Lz4
}

/// Default disk cache shards
#[inline]
#[must_use]
pub const fn disk_cache_shards() -> usize {
    4
}

/// Default backend idle timeout (10 minutes)
///
/// After this duration of proxy-wide inactivity, idle backend connections are cleared.
/// Prevents stale connections from accumulating during overnight idle periods.
#[inline]
pub const fn backend_idle_timeout() -> Duration {
    crate::constants::duration_polyfill::from_minutes(10)
}

/// Default connection replacement cooldown.
#[inline]
pub const fn replacement_cooldown() -> Duration {
    Duration::from_secs(30)
}

/// Default connection replacement cooldown option.
#[inline]
#[allow(clippy::unnecessary_wraps)] // Config defaults model an optional field even when the default is always present.
pub const fn replacement_cooldown_option() -> Option<Duration> {
    Some(replacement_cooldown())
}

/// Default log file level (warn)
#[inline]
pub fn log_file_level() -> String {
    "warn".to_string()
}
