//! Server configuration

use serde::{Deserialize, Serialize};
use std::net::SocketAddr;

/// 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,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum OvnMode {
    Mock,
    Real,
}

impl Default for OvnMode {
    fn default() -> Self {
        Self::Mock
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OvnConfig {
    #[serde(default)]
    pub mode: OvnMode,
    #[serde(default = "default_ovn_nb_addr")]
    pub nb_addr: String,
}

impl Default for OvnConfig {
    fn default() -> Self {
        Self {
            mode: OvnMode::default(),
            nb_addr: default_ovn_nb_addr(),
        }
    }
}

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

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

/// Server configuration
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerConfig {
    /// gRPC API address
    pub grpc_addr: SocketAddr,

    /// HTTP REST API address
    #[serde(default = "default_http_addr")]
    pub http_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 mode (required for SQLite)
    #[serde(default)]
    pub single_node: bool,

    /// Log level
    pub log_level: String,

    /// TLS configuration (optional)
    pub tls: Option<TlsConfig>,

    /// Authentication configuration
    #[serde(default)]
    pub auth: AuthConfig,

    /// OVN integration settings
    #[serde(default)]
    pub ovn: OvnConfig,
}

/// 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(),
        }
    }
}

fn default_http_addr() -> SocketAddr {
    "127.0.0.1:8087".parse().unwrap()
}

fn default_ovn_nb_addr() -> String {
    "tcp:127.0.0.1:6641".to_string()
}

impl Default for ServerConfig {
    fn default() -> Self {
        Self {
            grpc_addr: "0.0.0.0:9090".parse().unwrap(),
            http_addr: default_http_addr(),
            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(),
            ovn: OvnConfig::default(),
        }
    }
}
