use std::{net::SocketAddr, path::PathBuf};

use anyhow::Context;

mod routes;
mod static_files;

#[derive(Debug, Clone)]
pub struct ServerState {
    pub root_dir: PathBuf,
    pub output_dir: PathBuf,
    pub edit: bool,
}

pub async fn serve(
    root_dir: PathBuf,
    output_dir: PathBuf,
    host: String,
    port: u16,
    edit: bool,
) -> anyhow::Result<()> {
    let addr: SocketAddr = format!("{host}:{port}")
        .parse()
        .with_context(|| format!("invalid listen address {host}:{port}"))?;
    let state = ServerState {
        root_dir,
        output_dir: output_dir.clone(),
        edit,
    };
    let app = routes::router(state);
    let listener = tokio::net::TcpListener::bind(addr)
        .await
        .with_context(|| format!("failed to bind {addr}"))?;
    let edit_suffix = if edit { " (edit enabled)" } else { "" };
    println!("serving http://{addr}{edit_suffix}");
    axum::serve(listener, app).await?;
    Ok(())
}
