mod v0;

use std::sync::Arc;

use axum::Router;
use config::Config;
use serde::Deserialize;
use tokio::net::TcpListener;

fn default_port() -> u16 {
    3001
}

#[derive(Deserialize, Debug)]
struct Configuration {
    #[serde(default = "default_port")]
    port: u16,
}

#[derive(Debug)]
struct AppState {
    config: Configuration,
}

#[tokio::main]
async fn main() -> color_eyre::Result<()> {
    color_eyre::install()?;
    tracing_subscriber::fmt()
        .pretty()
        .with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
        .init();
    let config: Configuration = Config::builder()
        .add_source(config::File::with_name("settings"))
        .add_source(config::Environment::with_prefix("CARDSERV"))
        .build()?
        .try_deserialize()?;
    let port = config.port;
    let state = Arc::new(AppState { config });

    let app = Router::new()
        .with_state(state)
        .nest("/v0", v0::router())
        //.route_layer(tower_http::compression::CompressionLayer::new())
        .layer(tower_http::trace::TraceLayer::new_for_http());
    let listener = TcpListener::bind(("0.0.0.0", port)).await?;
    tracing::info!(port=%port, "Listening on 0.0.0.0");
    axum::serve(listener, app).await?;
    Ok(())
}