use crate::{rest, ws};
use axum::routing::{get, post};
use axum::Router;
use harness_core::Runtime;
use std::time::Instant;
use tower_http::trace::TraceLayer;
#[derive(Clone)]
pub struct AppState {
pub runtime: Runtime,
pub started: Instant,
pub version: &'static str,
pub require_pairing: bool,
}
impl AppState {
pub fn new(runtime: Runtime) -> Self {
let require_pairing = runtime.config().server.require_pairing;
AppState {
runtime,
started: Instant::now(),
version: env!("CARGO_PKG_VERSION"),
require_pairing,
}
}
pub fn uptime_secs(&self) -> u64 {
self.started.elapsed().as_secs()
}
pub fn accepts_token(&self, token: Option<&str>) -> bool {
if !self.require_pairing {
return true;
}
match token {
Some(t) => self
.runtime
.store()
.device_hash_exists(&crate::auth::hash(t))
.unwrap_or(false),
None => false,
}
}
}
pub fn router(state: AppState) -> Router {
Router::new()
.route("/v1/health", get(rest::health))
.route("/v1/version", get(rest::version))
.route(
"/v1/sessions",
get(rest::list_sessions).post(rest::create_session),
)
.route("/v1/sessions/:id/events", get(rest::session_events))
.route(
"/v1/providers",
get(rest::list_providers).post(rest::add_provider),
)
.route("/v1/providers/:id/key", post(rest::set_provider_key))
.route("/v1/presets", get(rest::list_presets))
.route(
"/v1/presets/:id/requirements",
get(rest::preset_requirements),
)
.route("/v1/pair/start", post(rest::pair_start))
.route("/v1/pair/complete", post(rest::pair_complete))
.route("/v1/ws", get(ws::handler))
.layer(TraceLayer::new_for_http())
.with_state(state)
}