mod app;
mod archive;
pub mod auth;
mod clock;
mod config;
mod dev;
mod extract;
mod forum;
#[cfg(test)]
pub(crate) mod test;
mod users;

pub use crate::dev::DevApi;
pub use crate::extract::InternalAuthKey;
use axum::body::Body;
use axum::extract::Extension;
use axum::Router;
use etwin_core::clock::Clock;
use etwin_core::types::AnyError;
use etwin_services::auth::DynAuthService;
use etwin_services::dinoparc::DynDinoparcService;
use etwin_services::forum::DynForumService;
use etwin_services::hammerfest::DynHammerfestService;
use etwin_services::twinoid::DynTwinoidService;
use etwin_services::user::DynUserService;
pub use serde::Serialize;
use std::sync::Arc;

#[derive(Debug)]
struct ServerError(AnyError);

#[derive(Clone)]
pub struct RouterApi {
  pub dev: DevApi,
  pub auth: Arc<DynAuthService>,
  pub clock: Arc<dyn Clock>,
  pub dinoparc: Arc<DynDinoparcService>,
  pub forum: Arc<DynForumService>,
  pub hammerfest: Arc<DynHammerfestService>,
  pub twinoid: Arc<DynTwinoidService>,
  pub user: Arc<DynUserService>,
}

pub fn router() -> Router<Body> {
  Router::new()
    .nest("/app", app::router())
    .nest("/archive", archive::router())
    .nest("/auth", auth::router())
    .nest("/clock", clock::router())
    .nest("/config", config::router())
    .nest("/forum", forum::router())
    .nest("/hammerfest_client", dev::hammerfest_client::router())
    .nest("/users", users::router())
}

pub fn app(api: RouterApi, internal_key: Option<InternalAuthKey>) -> Router<Body> {
  let router = Router::new()
    .nest("/api/v1", router())
    .layer(Extension(api.dev.clone()))
    .layer(Extension(api));
  if let Some(internal_key) = internal_key {
    router.layer(Extension(internal_key))
  } else {
    router
  }
}
