opencrates 3.0.1

Enterprise-grade AI-powered Rust development companion with comprehensive automation, monitoring, and deployment capabilities
use anyhow::Result;
use clap::Parser;
use dotenvy::dotenv;
use opencrates::server::run_server;
use opencrates::utils::{config::OpenCratesConfig, logging};
use tokio::signal;
use tracing::Level;

#[cfg(not(feature = "tracing"))]
use log::{info, warn};
#[cfg(feature = "tracing")]
use tracing::{info, warn};

#[derive(Parser)]
#[command(name = "opencrates-server")]
#[command(about = "OpenCrates standalone server")]
#[command(version)]
struct Args {
    /// Server host address
    #[arg(long, default_value = "0.0.0.0")]
    host: String,

    /// Server port
    #[arg(short, long, default_value = "8080")]
    port: u16,

    /// Number of worker threads
    #[arg(short, long, default_value = "4")]
    workers: usize,

    /// Configuration file path
    #[arg(short, long)]
    config: Option<String>,

    /// Enable debug mode
    #[arg(short, long)]
    debug: bool,

    /// Enable metrics endpoint
    #[arg(long)]
    metrics: bool,

    /// Enable admin API
    #[arg(long)]
    admin: bool,
}

#[tokio::main]
async fn main() -> Result<()> {
    // Load environment variables from .env file if it exists
    dotenv().ok();
    
    let args = Args::parse();

    // Initialize logging
    let level = if args.debug {
        Level::DEBUG
    } else {
        Level::INFO
    };
    logging::init(level);

    info!("Starting OpenCrates Server v{}", env!("CARGO_PKG_VERSION"));

    // Create configuration
    let config = OpenCratesConfig::default();

    info!("Server will bind to: {}:{}", args.host, args.port);

    if args.metrics {
        info!("Metrics endpoint enabled at /metrics");
    }

    if args.admin {
        info!("Admin API enabled");
    }

    // Setup graceful shutdown
    tokio::spawn(async move {
        shutdown_signal().await;
        warn!("Shutdown signal received, starting graceful shutdown...");
    });

    // Start server
    info!("OpenCrates Server starting on {}:{}", args.host, args.port);
    run_server(config).await?;

    info!("OpenCrates Server shutdown complete");
    Ok(())
}

async fn shutdown_signal() {
    let ctrl_c = async {
        signal::ctrl_c()
            .await
            .expect("failed to install Ctrl+C handler");
    };

    #[cfg(unix)]
    let terminate = async {
        signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("failed to install signal handler")
            .recv()
            .await;
    };

    #[cfg(not(unix))]
    let terminate = std::future::pending::<()>();

    tokio::select! {
        _ = ctrl_c => {},
        _ = terminate => {},
    }
}