use auth_framework::{
admin::{AppState, CliCommand},
config::AuthFrameworkSettings,
errors::Result,
};
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "auth-framework")]
#[command(about = "Auth Framework Administration - CLI, TUI, and Web GUI")]
#[command(version)]
pub struct Args {
#[arg(short, long, default_value = "config/auth-framework.toml")]
pub config: String,
#[arg(long, default_value = "AUTH_FRAMEWORK")]
pub env_prefix: String,
#[arg(short, long)]
pub verbose: bool,
#[command(subcommand)]
pub interface: Interface,
}
#[derive(Subcommand)]
pub enum Interface {
Cli {
#[command(subcommand)]
command: CliCommand,
},
#[cfg(feature = "tui")]
Tui {
#[arg(long)]
readonly: bool,
},
#[cfg(feature = "web-gui")]
WebGui {
#[arg(short, long, default_value_t = 8080)]
port: u16,
#[arg(long, default_value = "127.0.0.1")]
host: String,
#[arg(short, long)]
daemon: bool,
},
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
init_logging(args.verbose);
let settings = load_config(&args.config, &args.env_prefix).await?;
let auth_framework = {
let mut af = auth_framework::AuthFramework::new(settings.auth.clone());
if let Err(e) = af.initialize().await {
tracing::warn!(error = %e, "AuthFramework initialisation failed; storage queries will return empty results");
}
std::sync::Arc::new(af)
};
let app_state = AppState::new(settings)?.with_auth_framework(auth_framework);
match args.interface {
Interface::Cli { command } => {
#[cfg(feature = "cli")]
{
use auth_framework::admin::cli;
cli::run_cli(app_state, command).await?;
}
#[cfg(not(feature = "cli"))]
{
eprintln!("CLI feature not enabled. Rebuild with --features cli");
std::process::exit(1);
}
}
#[cfg(feature = "tui")]
Interface::Tui { readonly } => {
use auth_framework::admin::tui;
tui::run_tui(app_state, readonly).await?;
}
#[cfg(feature = "web-gui")]
Interface::WebGui { port, host, daemon } => {
use auth_framework::admin::web;
web::run_web_gui(app_state, &host, port, daemon, true).await?;
}
}
Ok(())
}
fn init_logging(verbose: bool) {
if verbose {
println!("🔧 Verbose logging enabled");
}
}
async fn load_config(
config_path: &str,
env_prefix: &str,
) -> Result<AuthFrameworkSettings, Box<dyn std::error::Error>> {
let settings = AuthFrameworkSettings::default();
println!("✅ Configuration loaded from {}", config_path);
println!("🔧 Environment prefix: {}", env_prefix);
Ok(settings)
}