use std::{net::SocketAddr, time::Duration};
use anyhow::anyhow;
use clap::Args;
use humantime::parse_duration;
use ic_bn_lib_common::parse_size;
use url::Url;
use crate::smtp::inbound::SessionConfig;
#[derive(Args, Clone, Debug, Eq, PartialEq)]
pub struct SmtpServerCli {
#[clap(env, long, requires = "smtp_server_hostname")]
pub smtp_server_listen: Option<SocketAddr>,
#[clap(env, long, requires = "smtp_server_listen")]
pub smtp_server_hostname: Option<String>,
#[clap(env, long, default_value = "icp0.io")]
pub smtp_server_ic_base_domain: String,
#[clap(env, long, default_value = "2s", value_parser = parse_duration)]
pub smtp_server_greeting_delay: Duration,
#[clap(env, long, default_value = "10")]
pub smtp_server_max_recipients: usize,
#[clap(env, long, default_value = "5")]
pub smtp_server_max_messages_per_session: usize,
#[clap(env, long, default_value = "5")]
pub smtp_server_max_errors_per_session: usize,
#[clap(env, long, default_value = "1950KB", value_parser = parse_size)]
pub smtp_server_max_message_size: u64,
#[clap(env, long, default_value = "50MB", value_parser = parse_size)]
pub smtp_server_max_session_data: u64,
#[clap(env, long, default_value = "2m", value_parser = parse_duration)]
pub smtp_server_max_session_duration: Duration,
#[clap(env, long, default_value = "30s", value_parser = parse_duration)]
pub smtp_server_timeout: Duration,
#[clap(env, long, default_value = "10m", value_parser = parse_duration)]
pub smtp_server_canister_cache_ttl: Duration,
#[clap(env, long, default_value = "100k", value_parser = parse_size)]
pub smtp_server_canister_cache_capacity: u64,
#[clap(env, long)]
pub smtp_server_tls_required: bool,
#[clap(env, long)]
pub smtp_server_verify_ehlo_hostname: bool,
#[clap(env, long)]
pub smtp_server_verify_reverse_ip: bool,
#[clap(env, long)]
pub smtp_server_verify_reverse_ip_strict: bool,
#[clap(env, long)]
pub smtp_server_verify_sender_domain: bool,
#[clap(env, long)]
pub smtp_server_verify_spf: bool,
#[clap(env, long)]
pub smtp_server_verify_dkim: bool,
#[clap(env, long)]
pub smtp_server_verify_dkim_strict: bool,
#[clap(env, long)]
pub smtp_server_vector_url: Option<Url>,
#[clap(env, long)]
pub smtp_server_vector_user: Option<String>,
#[clap(env, long)]
pub smtp_server_vector_pass: Option<String>,
}
impl TryFrom<&SmtpServerCli> for SessionConfig {
type Error = anyhow::Error;
fn try_from(v: &SmtpServerCli) -> Result<Self, Self::Error> {
let Some(hostname) = &v.smtp_server_hostname else {
return Err(anyhow!("`smtp_server_hostname` is required"));
};
let mut cfg = Self::new(hostname, v.smtp_server_max_message_size as usize);
cfg.greeting_delay = Some(v.smtp_server_greeting_delay);
cfg.max_errors = v.smtp_server_max_errors_per_session;
cfg.max_messages_per_session = v.smtp_server_max_messages_per_session;
cfg.max_recipients = v.smtp_server_max_recipients;
cfg.max_session_data = v.smtp_server_max_session_data as usize;
cfg.max_session_duration = v.smtp_server_max_session_duration;
cfg.timeout = v.smtp_server_timeout;
cfg.verify_ehlo_hostname = v.smtp_server_verify_ehlo_hostname;
cfg.verify_reverse_ip = v.smtp_server_verify_reverse_ip;
cfg.verify_reverse_ip_strict = v.smtp_server_verify_reverse_ip_strict;
cfg.verify_sender_domain = v.smtp_server_verify_sender_domain;
cfg.verify_spf = v.smtp_server_verify_spf;
cfg.verify_dkim = v.smtp_server_verify_dkim;
cfg.verify_dkim_strict = v.smtp_server_verify_dkim_strict;
Ok(cfg)
}
}