1use std::sync::Arc;
6
7use axum::extract::Extension;
8use axum::http::StatusCode;
9use axum::response::IntoResponse;
10use axum::routing::get;
11use axum::{Json, Router};
12use serde::Serialize;
13use utoipa::ToSchema;
14
15use crate::instance::Instance;
16use crate::RuntimeCore;
17
18pub mod paths {
20 pub const PREFIX: &str = "/v1/runtime";
21 pub const STATUS: &str = "/v1/runtime/status";
22 pub const INSTANCES: &str = "/v1/runtime/instances";
23
24 pub fn rel(full: &str) -> &str {
25 full.strip_prefix(PREFIX).unwrap_or(full)
26 }
27}
28
29pub fn routes(core: Arc<RuntimeCore>) -> Router {
31 use paths::rel;
32 Router::new()
33 .route(rel(paths::STATUS), get(status_handler))
34 .route(rel(paths::INSTANCES), get(instances_handler))
35 .layer(Extension(core))
36}
37
38#[derive(Debug, Serialize, ToSchema)]
40pub struct RuntimeStatus {
41 pub active: bool,
43 pub backend: Option<String>,
45 pub instance_count: usize,
47}
48
49#[utoipa::path(get, path = "/status", tag = "runtime",
51 summary = "Runtime adapter status",
52 responses((status = 200, body = RuntimeStatus)))]
53async fn status_handler(Extension(core): Extension<Arc<RuntimeCore>>) -> impl IntoResponse {
54 let status = core.status().await;
55 Json(status)
56}
57
58#[utoipa::path(get, path = "/instances", tag = "runtime",
60 summary = "List runtime-managed instances",
61 responses((status = 200, body = Vec<Instance>)))]
62async fn instances_handler(Extension(core): Extension<Arc<RuntimeCore>>) -> impl IntoResponse {
63 match core.list_instances().await {
64 Ok(instances) => (StatusCode::OK, Json(instances)).into_response(),
65 Err(e) => {
66 let code = koi_common::error::ErrorCode::from(&e);
67 let status = StatusCode::from_u16(code.http_status())
68 .unwrap_or(StatusCode::INTERNAL_SERVER_ERROR);
69 koi_common::http::error_response_with_status(status, code, e.to_string())
70 }
71 }
72}
73
74#[derive(utoipa::OpenApi)]
76#[openapi(
77 paths(status_handler, instances_handler),
78 components(schemas(
79 RuntimeStatus,
80 Instance,
81 crate::instance::PortMapping,
82 crate::instance::PortProtocol,
83 crate::instance::InstanceState,
84 crate::instance::KoiMetadata,
85 ))
86)]
87pub struct RuntimeApiDoc;