use serde::Deserialize;

/// SMTP 收信服务配置（临时邮箱核心）
#[derive(Debug, Deserialize, Clone)]
pub struct SmtpConfig {
    /// 是否启用 SMTP 收信（监听 25 端口）
    #[serde(default = "default_enabled")]
    pub enabled: bool,
    /// 监听地址
    #[serde(default = "default_listen_host")]
    pub listen_host: String,
    /// 监听端口（默认 25）
    #[serde(default = "default_listen_port")]
    pub listen_port: u16,
    /// 本机主机名（SMTP 问候时使用，如 mail.shenjianl.cn）
    #[serde(default = "default_hostname")]
    pub hostname: String,
    /// 允许的收件域名白名单（只收这些域名的邮件）
    #[serde(default = "default_local_domains")]
    pub local_domains: Vec<String>,
    /// 单封邮件最大字节数
    #[serde(default = "default_max_message_bytes")]
    pub max_message_bytes: usize,
    /// 单连接超时秒数
    #[serde(default = "default_connection_timeout_seconds")]
    pub connection_timeout_seconds: u64,
    /// 单封邮件最大收件人数
    #[serde(default = "default_max_recipients")]
    pub max_recipients_per_message: u32,

    // ===== 限流（IP 连接 + 发件域 + 收件地址） =====
    /// 单 IP 每分钟最大连接数
    #[serde(default = "default_ip_connect_per_min")]
    pub ip_connect_per_min: u32,
    /// 单发件域每分钟最大邮件数
    #[serde(default = "default_domain_per_min")]
    pub domain_per_min: u32,
    /// 单收件地址每分钟最大邮件数
    #[serde(default = "default_rcpt_per_min")]
    pub rcpt_per_min: u32,
    /// 单发件人每分钟最大邮件数
    #[serde(default = "default_sender_per_min")]
    pub sender_per_min: u32,
    /// 单（发件域→收件地址）每 10 分钟最大邮件数
    #[serde(default = "default_pair_per_10min")]
    pub pair_per_10min: u32,

    // ===== PTR 反查 =====
    /// 是否要求来源 IP 有有效 PTR 记录
    #[serde(default = "default_require_ptr")]
    pub require_ptr: bool,

    // ===== 灰名单 =====
    #[serde(default = "default_greylist_enabled")]
    pub greylist_enabled: bool,
    #[serde(default = "default_greylist_retry_delay_seconds")]
    pub greylist_retry_delay_seconds: i64,
    #[serde(default = "default_greylist_entry_ttl_seconds")]
    pub greylist_entry_ttl_seconds: i64,

    // ===== 滥用评分 =====
    /// 达到此分数的邮件进入隔离区
    #[serde(default = "default_quarantine_threshold")]
    pub quarantine_threshold: i32,
    #[serde(default = "default_score_weight_subject_code")]
    pub score_weight_subject_code: i32,
    #[serde(default = "default_score_weight_spf_fail")]
    pub score_weight_spf_fail: i32,
    #[serde(default = "default_score_weight_ptr_missing")]
    pub score_weight_ptr_missing: i32,
    #[serde(default = "default_score_weight_bad_attachment")]
    pub score_weight_bad_attachment: i32,

    // ===== 保留期与配额 =====
    /// 邮件保留天数（超过自动清理）
    #[serde(default = "default_email_ttl_days")]
    pub email_ttl_days: i64,
    /// 新建临时邮箱默认有效期（小时）
    #[serde(default = "default_mailbox_ttl_hours")]
    pub mailbox_ttl_hours: i64,
    /// 单邮箱最大容量（字节）
    #[serde(default = "default_mailbox_max_quota_bytes")]
    pub mailbox_max_quota_bytes: i64,
    /// 随机生成的邮箱本地部分长度
    #[serde(default = "default_address_local_part_len")]
    pub address_local_part_len: usize,
    /// 邮件正文加密密钥（必须恰好 32 字符；留空则不加密）
    #[serde(default)]
    pub body_encryption_key: String,
}

fn default_enabled() -> bool {
    true
}
fn default_listen_host() -> String {
    "0.0.0.0".to_string()
}
fn default_listen_port() -> u16 {
    25
}
fn default_hostname() -> String {
    "mail.shenjianl.cn".to_string()
}
fn default_local_domains() -> Vec<String> {
    vec!["mail.shenjianl.cn".to_string(), "shenjianl.cn".to_string()]
}
fn default_max_message_bytes() -> usize {
    1024 * 1024
}
fn default_connection_timeout_seconds() -> u64 {
    30
}
fn default_max_recipients() -> u32 {
    1
}
fn default_ip_connect_per_min() -> u32 {
    20
}
fn default_domain_per_min() -> u32 {
    10
}
fn default_rcpt_per_min() -> u32 {
    10
}
fn default_sender_per_min() -> u32 {
    10
}
fn default_pair_per_10min() -> u32 {
    5
}
fn default_require_ptr() -> bool {
    true
}
fn default_greylist_enabled() -> bool {
    true
}
fn default_greylist_retry_delay_seconds() -> i64 {
    300
}
fn default_greylist_entry_ttl_seconds() -> i64 {
    86400
}
fn default_quarantine_threshold() -> i32 {
    60
}
fn default_score_weight_subject_code() -> i32 {
    30
}
fn default_score_weight_spf_fail() -> i32 {
    20
}
fn default_score_weight_ptr_missing() -> i32 {
    15
}
fn default_score_weight_bad_attachment() -> i32 {
    25
}
fn default_email_ttl_days() -> i64 {
    7
}
fn default_mailbox_ttl_hours() -> i64 {
    24
}
fn default_mailbox_max_quota_bytes() -> i64 {
    10 * 1024 * 1024
}
fn default_address_local_part_len() -> usize {
    10
}

impl Default for SmtpConfig {
    fn default() -> Self {
        Self {
            enabled: default_enabled(),
            listen_host: default_listen_host(),
            listen_port: default_listen_port(),
            hostname: default_hostname(),
            local_domains: default_local_domains(),
            max_message_bytes: default_max_message_bytes(),
            connection_timeout_seconds: default_connection_timeout_seconds(),
            max_recipients_per_message: default_max_recipients(),
            ip_connect_per_min: default_ip_connect_per_min(),
            domain_per_min: default_domain_per_min(),
            rcpt_per_min: default_rcpt_per_min(),
            sender_per_min: default_sender_per_min(),
            pair_per_10min: default_pair_per_10min(),
            require_ptr: default_require_ptr(),
            greylist_enabled: default_greylist_enabled(),
            greylist_retry_delay_seconds: default_greylist_retry_delay_seconds(),
            greylist_entry_ttl_seconds: default_greylist_entry_ttl_seconds(),
            quarantine_threshold: default_quarantine_threshold(),
            score_weight_subject_code: default_score_weight_subject_code(),
            score_weight_spf_fail: default_score_weight_spf_fail(),
            score_weight_ptr_missing: default_score_weight_ptr_missing(),
            score_weight_bad_attachment: default_score_weight_bad_attachment(),
            email_ttl_days: default_email_ttl_days(),
            mailbox_ttl_hours: default_mailbox_ttl_hours(),
            mailbox_max_quota_bytes: default_mailbox_max_quota_bytes(),
            address_local_part_len: default_address_local_part_len(),
            body_encryption_key: String::new(),
        }
    }
}
