use axum::routing::{get, post};
use axum::Router;
use std::sync::Arc;
use swarm_core::config::SwarmConfig;
use swarm_core::error::SwarmResult;
use swarm_core::orchestrator::Orchestrator;
use swarm_llm::ProviderRegistry;
use swarm_tools::ToolRegistry;
use tower_http::cors::CorsLayer;
use tower_http::trace::TraceLayer;
use tracing::info;
use crate::routes;
use crate::state::AppState;
pub async fn serve(
orchestrator: Arc<Orchestrator>,
providers: Arc<ProviderRegistry>,
tools: Arc<ToolRegistry>,
config: &SwarmConfig,
) -> SwarmResult<()> {
let state = AppState {
orchestrator,
providers,
tools,
};
let app = Router::new()
.route("/health", get(routes::health))
.route("/agents", get(routes::list_agents))
.route("/chat", post(routes::chat))
.route("/providers", get(routes::list_providers))
.route("/tools", get(routes::list_tools))
.route("/message", post(routes::send_message))
.route("/route", post(routes::route_task))
.layer(CorsLayer::permissive())
.layer(TraceLayer::new_for_http())
.with_state(state);
let addr = format!("{}:{}", config.gateway.host, config.gateway.port);
info!(addr = %addr, "Gateway listening");
let listener = tokio::net::TcpListener::bind(&addr).await?;
axum::serve(listener, app)
.await
.map_err(|e| swarm_core::error::SwarmError::Other(e.into()))?;
Ok(())
}