use std::sync::Arc;
use axum::{
extract::{Path, Query, State},
Json,
};
use oxios_kernel::{ClawHubSearchResult, ClawHubSkillDetail};
use crate::error::AppError;
use crate::server::AppState;
#[derive(Debug, serde::Deserialize)]
pub struct SearchQuery {
pub q: String,
#[serde(default = "default_limit")]
pub limit: usize,
}
fn default_limit() -> usize {
20
}
#[derive(Debug, serde::Deserialize)]
pub struct InstallBody {
pub version: Option<String>,
}
pub(crate) async fn handle_marketplace_search(
state: State<Arc<AppState>>,
Query(query): Query<SearchQuery>,
) -> Result<Json<Vec<ClawHubSearchResult>>, AppError> {
let results = state
.kernel
.marketplace_api()
.search(&query.q, Some(query.limit))
.await
.map_err(|e| AppError::Internal(e.to_string()))?;
Ok(Json(results))
}
pub(crate) async fn handle_marketplace_skill_detail(
state: State<Arc<AppState>>,
Path(slug): Path<String>,
) -> Result<Json<ClawHubSkillDetail>, AppError> {
let detail = state
.kernel
.marketplace_api()
.get_skill(&slug)
.await
.map_err(|e| AppError::Internal(e.to_string()))?;
Ok(Json(detail))
}
pub(crate) async fn handle_marketplace_install(
state: State<Arc<AppState>>,
Path(slug): Path<String>,
Json(body): Json<InstallBody>,
) -> Result<Json<serde_json::Value>, AppError> {
let result = state
.kernel
.marketplace_api()
.install(&slug, body.version.as_deref())
.await
.map_err(|e| AppError::Internal(e.to_string()))?;
Ok(Json(serde_json::json!({
"ok": result.ok,
"slug": result.slug,
"version": result.version,
"targetDir": result.target_dir.to_string_lossy(),
"changelog": result.changelog,
})))
}
pub(crate) async fn handle_marketplace_updates(
state: State<Arc<AppState>>,
) -> Result<Json<Vec<serde_json::Value>>, AppError> {
let updates = state
.kernel
.marketplace_api()
.check_updates()
.await
.map_err(|e| AppError::Internal(e.to_string()))?;
let results: Vec<serde_json::Value> = updates
.into_iter()
.map(|u| {
serde_json::json!({
"slug": u.slug,
"currentVersion": u.current_version,
"latestVersion": u.latest_version,
"changelog": u.changelog,
})
})
.collect();
Ok(Json(results))
}