use std::net::SocketAddr;
use std::path::PathBuf;
use std::time::Duration;
use clap::{Parser, Subcommand};
#[derive(Parser, Debug)]
#[command(name = "tsoracle", version, about = "Standalone timestamp oracle")]
pub struct Cli {
#[command(subcommand)]
pub cmd: Option<Cmd>,
#[command(flatten)]
pub serve_file: FileArgs,
}
#[derive(Subcommand, Debug)]
pub enum Cmd {
#[command(subcommand)]
Serve(Box<ServeCmd>),
Init(InitArgs),
#[cfg(feature = "openraft")]
#[command(subcommand)]
Admin(AdminCmd),
}
#[cfg(feature = "openraft")]
#[derive(Subcommand, Debug)]
pub enum AdminCmd {
Members(AdminEndpointArgs),
AddLearner(AddLearnerArgs),
Promote(AdminIdArgs),
Remove(AdminIdArgs),
ActivateFormat(ActivateFormatArgs),
}
#[cfg(feature = "openraft")]
#[derive(Parser, Debug, Clone)]
pub struct AdminClientTlsArgs {
#[arg(long)]
pub client_tls_cert: Option<std::path::PathBuf>,
#[arg(long)]
pub client_tls_key: Option<std::path::PathBuf>,
#[arg(long)]
pub client_tls_ca: Option<std::path::PathBuf>,
}
#[cfg(feature = "openraft")]
#[derive(Parser, Debug)]
pub struct AdminEndpointArgs {
#[arg(long)]
pub endpoint: String,
#[command(flatten)]
pub tls: AdminClientTlsArgs,
}
#[cfg(feature = "openraft")]
#[derive(Parser, Debug)]
pub struct AdminIdArgs {
#[arg(long)]
pub endpoint: String,
#[arg(long)]
pub id: u64,
#[command(flatten)]
pub tls: AdminClientTlsArgs,
}
#[cfg(feature = "openraft")]
#[derive(Parser, Debug)]
pub struct AddLearnerArgs {
#[arg(long)]
pub endpoint: String,
#[arg(long)]
pub id: u64,
#[arg(long)]
pub raft_addr: String,
#[arg(long)]
pub service_endpoint: String,
#[arg(long)]
pub admin_endpoint: String,
#[command(flatten)]
pub tls: AdminClientTlsArgs,
}
#[cfg(feature = "openraft")]
#[derive(Parser, Debug)]
pub struct ActivateFormatArgs {
#[arg(long)]
pub endpoint: String,
#[arg(long)]
pub target: u8,
#[command(flatten)]
pub tls: AdminClientTlsArgs,
}
#[derive(Subcommand, Debug)]
pub enum ServeCmd {
File(FileArgs),
Openraft(OpenraftArgs),
Paxos(PaxosArgs),
}
#[derive(Parser, Debug, Clone)]
pub struct CommonServeArgs {
#[arg(long, default_value = "127.0.0.1:50551")]
pub listen: SocketAddr,
#[arg(long, value_parser = parse_duration, default_value = "3s")]
pub window_ahead: Duration,
#[arg(long, value_parser = parse_duration, default_value = "1s")]
pub failover_advance: Duration,
#[arg(long, value_parser = parse_duration, default_value = "10s")]
pub heartbeat_interval: Duration,
#[arg(long, default_value = "info")]
pub log: String,
#[arg(long)]
pub tls_cert: Option<std::path::PathBuf>,
#[arg(long)]
pub tls_key: Option<std::path::PathBuf>,
#[arg(long)]
pub tls_client_ca: Option<std::path::PathBuf>,
}
#[derive(Parser, Debug, Clone)]
pub struct FileArgs {
#[command(flatten)]
pub common: CommonServeArgs,
#[arg(long, default_value = "./tsoracle-data")]
pub state_dir: PathBuf,
}
#[derive(Parser, Debug, Clone)]
pub struct OpenraftArgs {
#[command(flatten)]
pub common: CommonServeArgs,
#[arg(long)]
pub id: u64,
#[arg(long)]
pub raft_addr: SocketAddr,
#[arg(long)]
pub raft_dir: PathBuf,
#[arg(long)]
pub bootstrap: bool,
#[arg(long)]
pub members: Option<String>,
#[arg(long, default_value = "250")]
pub heartbeat_ms: u64,
#[arg(long, default_value = "1000")]
pub election_min_ms: u64,
#[arg(long, default_value = "2000")]
pub election_max_ms: u64,
#[arg(long)]
pub admin_listen: Option<SocketAddr>,
#[arg(long)]
pub admin_tls_cert: Option<std::path::PathBuf>,
#[arg(long)]
pub admin_tls_key: Option<std::path::PathBuf>,
#[arg(long)]
pub admin_tls_ca: Option<std::path::PathBuf>,
#[arg(long)]
pub peer_tls_cert: Option<std::path::PathBuf>,
#[arg(long)]
pub peer_tls_key: Option<std::path::PathBuf>,
#[arg(long)]
pub peer_tls_ca: Option<std::path::PathBuf>,
#[arg(long)]
pub allow_insecure_peer: bool,
}
#[derive(Parser, Debug, Clone)]
pub struct PaxosArgs {
#[command(flatten)]
pub common: CommonServeArgs,
#[arg(long)]
pub node_id: u64,
#[arg(long)]
pub peer_listen: SocketAddr,
#[arg(long)]
pub peers: String,
#[arg(long)]
pub tso_peers: String,
#[arg(long)]
pub data_dir: PathBuf,
#[arg(long, value_parser = parse_duration, default_value = "20ms")]
pub tick_interval: Duration,
#[arg(long)]
pub peer_tls_cert: Option<std::path::PathBuf>,
#[arg(long)]
pub peer_tls_key: Option<std::path::PathBuf>,
#[arg(long)]
pub peer_tls_ca: Option<std::path::PathBuf>,
#[arg(long)]
pub allow_insecure_peer: bool,
}
#[derive(Parser, Debug)]
pub struct InitArgs {
#[arg(long, default_value = "./tsoracle-data")]
pub state_dir: PathBuf,
#[arg(long)]
pub seed_physical_ms: u64,
}
pub fn parse_duration(input: &str) -> Result<Duration, String> {
humantime::parse_duration(input).map_err(|e| e.to_string())
}