use clap::{Args, Parser};
use ipnetwork::IpNetwork;
#[derive(Clone, Debug, Parser)]
#[command(version, about, long_about = None)]
pub struct Config {
#[arg(long, env = "OBSCURA_DATABASE_URL")]
pub database_url: String,
#[arg(long, env = "OBSCURA_TTL_DAYS", default_value_t = 30)]
pub ttl_days: i64,
#[command(flatten)]
pub server: ServerConfig,
#[command(flatten)]
pub auth: AuthConfig,
#[command(flatten)]
pub rate_limit: RateLimitConfig,
#[command(flatten)]
pub messaging: MessagingConfig,
#[command(flatten)]
pub notifications: NotificationConfig,
#[command(flatten)]
pub websocket: WsConfig,
#[command(flatten)]
pub s3: S3Config,
}
#[derive(Clone, Debug, Args)]
pub struct ServerConfig {
#[arg(long, env = "OBSCURA_HOST", default_value = "0.0.0.0")]
pub host: String,
#[arg(long, env = "OBSCURA_PORT", default_value_t = 3000)]
pub port: u16,
#[arg(
long,
env = "OBSCURA_TRUSTED_PROXIES",
default_value = "10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,127.0.0.1/32",
value_delimiter = ','
)]
pub trusted_proxies: Vec<IpNetwork>,
}
#[derive(Clone, Debug, Args)]
pub struct AuthConfig {
#[arg(long, env = "OBSCURA_JWT_SECRET")]
pub jwt_secret: String,
#[arg(long, env = "OBSCURA_ACCESS_TOKEN_TTL_SECS", default_value_t = 900)]
pub access_token_ttl_secs: u64,
#[arg(long, env = "OBSCURA_REFRESH_TOKEN_TTL_DAYS", default_value_t = 30)]
pub refresh_token_ttl_days: i64,
}
#[derive(Clone, Debug, Args)]
pub struct RateLimitConfig {
#[arg(long, env = "OBSCURA_RATE_LIMIT_PER_SECOND", default_value_t = 10)]
pub per_second: u32,
#[arg(long, env = "OBSCURA_RATE_LIMIT_BURST", default_value_t = 20)]
pub burst: u32,
#[arg(long, env = "OBSCURA_AUTH_RATE_LIMIT_PER_SECOND", default_value_t = 1)]
pub auth_per_second: u32,
#[arg(long, env = "OBSCURA_AUTH_RATE_LIMIT_BURST", default_value_t = 3)]
pub auth_burst: u32,
}
#[derive(Clone, Debug, Args)]
pub struct MessagingConfig {
#[arg(long, env = "OBSCURA_MAX_INBOX_SIZE", default_value_t = 1000)]
pub max_inbox_size: i64,
#[arg(long, env = "OBSCURA_CLEANUP_INTERVAL_SECS", default_value_t = 300)]
pub cleanup_interval_secs: u64,
#[arg(long, env = "OBSCURA_BATCH_LIMIT", default_value_t = 50)]
pub batch_limit: i64,
#[arg(long, env = "OBSCURA_PRE_KEY_REFILL_THRESHOLD", default_value_t = 20)]
pub pre_key_refill_threshold: i32,
#[arg(long, env = "OBSCURA_MAX_PRE_KEYS", default_value_t = 100)]
pub max_pre_keys: i64,
}
#[derive(Clone, Debug, Args)]
pub struct NotificationConfig {
#[arg(long, env = "OBSCURA_GC_INTERVAL_SECS", default_value_t = 60)]
pub gc_interval_secs: u64,
#[arg(long, env = "OBSCURA_CHANNEL_CAPACITY", default_value_t = 16)]
pub channel_capacity: usize,
}
#[derive(Clone, Debug, Args)]
pub struct WsConfig {
#[arg(long, env = "OBSCURA_WS_OUTBOUND_BUFFER_SIZE", default_value_t = 32)]
pub outbound_buffer_size: usize,
#[arg(long, env = "OBSCURA_WS_ACK_BUFFER_SIZE", default_value_t = 100)]
pub ack_buffer_size: usize,
#[arg(long, env = "OBSCURA_WS_ACK_BATCH_SIZE", default_value_t = 50)]
pub ack_batch_size: usize,
#[arg(long, env = "OBSCURA_WS_ACK_FLUSH_INTERVAL_MS", default_value_t = 500)]
pub ack_flush_interval_ms: u64,
}
#[derive(Clone, Debug, Args)]
pub struct S3Config {
#[arg(long, env = "OBSCURA_S3_BUCKET")]
pub bucket: String,
#[arg(long, env = "OBSCURA_S3_REGION", default_value = "us-east-1")]
pub region: String,
#[arg(long, env = "OBSCURA_S3_ENDPOINT")]
pub endpoint: Option<String>,
#[arg(long, env = "OBSCURA_S3_ACCESS_KEY")]
pub access_key: Option<String>,
#[arg(long, env = "OBSCURA_S3_SECRET_KEY")]
pub secret_key: Option<String>,
#[arg(long, env = "OBSCURA_S3_FORCE_PATH_STYLE", default_value_t = false)]
pub force_path_style: bool,
#[arg(long, env = "OBSCURA_S3_MAX_SIZE_BYTES", default_value_t = 52_428_800)]
pub attachment_max_size_bytes: usize,
}
impl Config {
pub fn load() -> Self {
Self::parse()
}
}