use serde::{Deserialize, Serialize};
// Not used yet, but good for future expansion
use std::net::SocketAddr; // To parse addresses

/// TLS configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TlsConfig {
    /// Path to certificate file (PEM)
    pub cert_file: String,

    /// Path to private key file (PEM)
    pub key_file: String,

    /// Path to CA certificate for client verification (optional, for mTLS)
    pub ca_file: Option<String>,

    /// Require client certificates (mTLS)
    #[serde(default)]
    pub require_client_cert: bool,
}

/// Metadata storage backend
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum MetadataBackend {
    /// FlareDB distributed metadata database
    FlareDb,
    /// PostgreSQL (single node or external HA Postgres)
    Postgres,
    /// SQLite (single-node deployments only)
    Sqlite,
}

impl Default for MetadataBackend {
    fn default() -> Self {
        Self::FlareDb
    }
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ServerConfig {
    pub grpc_addr: SocketAddr,
    pub dns_addr: SocketAddr,
    /// ChainFire endpoint used for cluster coordination only
    pub chainfire_endpoint: Option<String>,
    /// FlareDB endpoint used for metadata and tenant data storage
    pub flaredb_endpoint: Option<String>,
    /// Metadata backend selection (flaredb, postgres, sqlite)
    #[serde(default)]
    pub metadata_backend: MetadataBackend,
    /// SQL database URL for metadata when backend is postgres or sqlite
    pub metadata_database_url: Option<String>,
    /// Allow single-node SQL mode (required for SQLite)
    #[serde(default)]
    pub single_node: bool,
    pub log_level: String,
    /// TLS configuration (optional)
    pub tls: Option<TlsConfig>,
    /// Authentication configuration
    #[serde(default)]
    pub auth: AuthConfig,
}

/// Authentication configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AuthConfig {
    /// IAM server endpoint
    #[serde(default = "default_iam_server_addr")]
    pub iam_server_addr: String,
}

fn default_iam_server_addr() -> String {
    "127.0.0.1:50051".to_string()
}

impl Default for AuthConfig {
    fn default() -> Self {
        Self {
            iam_server_addr: default_iam_server_addr(),
        }
    }
}

impl Default for ServerConfig {
    fn default() -> Self {
        Self {
            grpc_addr: "0.0.0.0:9053".parse().unwrap(),
            dns_addr: "0.0.0.0:5353".parse().unwrap(),
            chainfire_endpoint: None,
            flaredb_endpoint: None,
            metadata_backend: MetadataBackend::FlareDb,
            metadata_database_url: None,
            single_node: false,
            log_level: "info".to_string(),
            tls: None,
            auth: AuthConfig::default(),
        }
    }
}
