//! Health check endpoint — thin HTTP adapter over `service::health`.
//!
//! Domain logic (the `HealthStatus` type and check function) lives in
//! `service::health`; this module is a thin adapter: call service → shape
//! response.

pub use crate::service::health::HealthStatus;

use poem::handler;
use poem_openapi::{OpenApi, Tags, payload::Json};

/// Health check endpoint.
///
/// Returns a static "ok" response to indicate the server is running.
#[handler]
pub fn health() -> &'static str {
    "ok"
}

#[derive(Tags)]
enum HealthTags {
    Health,
}

pub struct HealthApi;

#[OpenApi(tag = "HealthTags::Health")]
impl HealthApi {
    /// Health check endpoint.
    ///
    /// Returns a JSON status object to confirm the server is running.
    #[oai(path = "/health", method = "get")]
    async fn health(&self) -> Json<HealthStatus> {
        Json(crate::service::health::check())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[tokio::test]
    async fn handler_health_returns_ok() {
        let app = poem::Route::new().at("/health", poem::get(health));
        let cli = poem::test::TestClient::new(app);
        let resp = cli.get("/health").send().await;
        resp.assert_status_is_ok();
        resp.assert_text("ok").await;
    }

    #[test]
    fn health_status_serializes_to_json() {
        let status = HealthStatus {
            status: "ok".to_string(),
        };
        let json = serde_json::to_value(&status).unwrap();
        assert_eq!(json["status"], "ok");
    }

    #[tokio::test]
    async fn api_health_returns_ok_status() {
        let api = HealthApi;
        let response = api.health().await;
        assert_eq!(response.0.status, "ok");
    }
}
