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

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ServerConfig {
    pub addr: SocketAddr,
    /// HTTP REST API listen address
    #[serde(default = "default_http_addr")]
    pub http_addr: SocketAddr,
    pub log_level: String,
}

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

impl Default for ServerConfig {
    fn default() -> Self {
        Self {
            addr: "[::]:6443".parse().unwrap(),
            http_addr: default_http_addr(),
            log_level: "info".to_string(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FlareDbConfig {
    pub pd_addr: Option<String>,
    pub direct_addr: Option<String>,
}

impl Default for FlareDbConfig {
    fn default() -> Self {
        Self {
            pd_addr: Some("127.0.0.1:2479".to_string()),
            direct_addr: None,
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct IamConfig {
    pub server_addr: String,
}

impl Default for IamConfig {
    fn default() -> Self {
        Self {
            server_addr: "http://127.0.0.1:50051".to_string(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FiberLbConfig {
    pub server_addr: String,
}

impl Default for FiberLbConfig {
    fn default() -> Self {
        Self {
            server_addr: "http://127.0.0.1:50082".to_string(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct FlashDnsConfig {
    pub server_addr: String,
}

impl Default for FlashDnsConfig {
    fn default() -> Self {
        Self {
            server_addr: "http://127.0.0.1:50053".to_string(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PrismNetConfig {
    pub server_addr: String,
}

impl Default for PrismNetConfig {
    fn default() -> Self {
        Self {
            server_addr: "http://127.0.0.1:9090".to_string(),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CreditServiceConfig {
    #[serde(default)]
    pub server_addr: Option<String>,
}

impl Default for CreditServiceConfig {
    fn default() -> Self {
        Self { server_addr: None }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ChainFireConfig {
    pub endpoint: Option<String>,
}

impl Default for ChainFireConfig {
    fn default() -> Self {
        Self {
            endpoint: Some("http://127.0.0.1:2379".to_string()),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct Config {
    pub server: ServerConfig,
    pub flaredb: FlareDbConfig,
    pub chainfire: ChainFireConfig,
    pub iam: IamConfig,
    #[serde(default)]
    pub creditservice: CreditServiceConfig,
    pub fiberlb: FiberLbConfig,
    pub flashdns: FlashDnsConfig,
    pub prismnet: PrismNetConfig,
}
