use std::net::SocketAddr;
use std::sync::Arc;

use axum::Router;
use clap::Parser;
use extension_registry::{ExtensionRegistry, API_VERSION, DEFAULT_PORT};
use tokio::net::TcpListener;

mod handlers;
use handlers::{routes, AppState};

#[derive(Parser)]
#[command(name = "extension-registry")]
#[command(about = "OCI-compliant extension registry proxy", long_about = None)]
struct Cli {
    /// Host to bind to
    #[arg(long, default_value = "127.0.0.1")]
    host: String,

    /// Port to bind to
    #[arg(long, default_value_t = DEFAULT_PORT)]
    port: u16,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Initialize tracing
    tracing_subscriber::fmt()
        .with_env_filter(
            tracing_subscriber::EnvFilter::from_default_env()
                .add_directive("info".parse().unwrap()),
        )
        .init();

    // Parse CLI arguments
    let cli = Cli::parse();

    // Create registry service
    let addr: SocketAddr = format!("{}:{}", cli.host, cli.port).parse()?;
    let registry = Arc::new(ExtensionRegistry::new(addr));

    // Create application state
    let state = AppState::new(registry);

    // Build router
    let app: Router = routes(state);

    // Bind to address
    let listener = TcpListener::bind(addr).await?;

    tracing::info!(
        "extension-registry v{} starting on {} (OCI v2 API)",
        API_VERSION,
        addr
    );

    // Run server
    axum::serve(listener, app).await?;

    Ok(())
}
