#![forbid(unsafe_code)]

pub mod analytics;
pub mod audit;
pub mod admin;
pub mod bets;
pub mod app_state;
pub mod config;
pub mod db;
pub mod events;
pub mod error;
pub mod experiments;
pub mod fixtures;
pub mod localization;
pub mod markets;
pub mod settlement;
pub mod sessions;
pub mod routes;
pub mod users;
pub mod telemetry;

use axum::Router;
use axum::Extension;
use tower_http::trace::TraceLayer;

use crate::{app_state::AppState, config::AppConfig};

pub fn build_router(state: AppState) -> Router {
    routes::router()
        .layer(Extension(state))
        .layer(TraceLayer::new_for_http())
}

pub async fn run() -> anyhow::Result<()> {
    let config = AppConfig::load()?;
    telemetry::init(&config.log_level);

    tracing::info!(
        service = %config.service_name,
        environment = %config.environment,
        version = %config.app_version,
        "starting Hermes backend"
    );

    let database_pool = db::connect_postgres(config.database_url.as_deref()).await?;
    let redis_client = db::connect_redis(config.redis_url.as_deref())?;

    let state = AppState::new(config.clone(), database_pool, redis_client);
    let app = build_router(state);
    let listener = tokio::net::TcpListener::bind(config.bind_addr).await?;

    tracing::info!(addr = %config.bind_addr, "listening");
    axum::serve(listener, app).await?;
    Ok(())
}
