use axum::Router;
use mockforge_core::config::{DeceptiveDeployConfig, HttpCorsConfig, RouteConfig};
use mockforge_chaos::core_failure_injection::FailureConfig;
use mockforge_core::intelligent_behavior::MockAI;
use mockforge_core::openapi::response::AiGenerator;
use mockforge_core::openapi_routes::ValidationOptions;
use mockforge_core::proxy::config::ProxyConfig;
use mockforge_core::request_chaining::ChainConfig;
use mockforge_chaos::core_traffic_shaping::TrafficShaper;
use mockforge_core::MultiTenantConfig;
use std::sync::Arc;
use tokio::sync::RwLock;
use crate::health::HealthManager;
pub struct HttpRouterBuilder {
spec_path: Option<String>,
validation_options: Option<ValidationOptions>,
failure_config: Option<FailureConfig>,
multi_tenant_config: Option<MultiTenantConfig>,
route_configs: Option<Vec<RouteConfig>>,
cors_config: Option<HttpCorsConfig>,
ai_generator: Option<Arc<dyn AiGenerator + Send + Sync>>,
mockai: Option<Arc<RwLock<MockAI>>>,
smtp_registry: Option<Arc<dyn std::any::Any + Send + Sync>>,
mqtt_broker: Option<Arc<dyn std::any::Any + Send + Sync>>,
traffic_shaper: Option<TrafficShaper>,
traffic_shaping_enabled: bool,
chain_config: Option<ChainConfig>,
health_manager: Option<Arc<HealthManager>>,
deceptive_deploy_config: Option<DeceptiveDeployConfig>,
proxy_config: Option<ProxyConfig>,
}
impl Default for HttpRouterBuilder {
fn default() -> Self {
Self::new()
}
}
impl HttpRouterBuilder {
pub fn new() -> Self {
Self {
spec_path: None,
validation_options: None,
failure_config: None,
multi_tenant_config: None,
route_configs: None,
cors_config: None,
ai_generator: None,
mockai: None,
smtp_registry: None,
mqtt_broker: None,
traffic_shaper: None,
traffic_shaping_enabled: false,
chain_config: None,
health_manager: None,
deceptive_deploy_config: None,
proxy_config: None,
}
}
pub fn spec_path(mut self, path: String) -> Self {
self.spec_path = Some(path);
self
}
pub fn spec_path_opt(mut self, path: Option<String>) -> Self {
self.spec_path = path;
self
}
pub fn validation_options(mut self, options: ValidationOptions) -> Self {
self.validation_options = Some(options);
self
}
pub fn validation_options_opt(mut self, options: Option<ValidationOptions>) -> Self {
self.validation_options = options;
self
}
pub fn failure_config(mut self, config: FailureConfig) -> Self {
self.failure_config = Some(config);
self
}
pub fn with_multi_tenant(mut self, config: MultiTenantConfig) -> Self {
self.multi_tenant_config = Some(config);
self
}
pub fn with_multi_tenant_opt(mut self, config: Option<MultiTenantConfig>) -> Self {
self.multi_tenant_config = config;
self
}
pub fn route_configs(mut self, configs: Vec<RouteConfig>) -> Self {
self.route_configs = Some(configs);
self
}
pub fn route_configs_opt(mut self, configs: Option<Vec<RouteConfig>>) -> Self {
self.route_configs = configs;
self
}
pub fn cors_config(mut self, config: HttpCorsConfig) -> Self {
self.cors_config = Some(config);
self
}
pub fn cors_config_opt(mut self, config: Option<HttpCorsConfig>) -> Self {
self.cors_config = config;
self
}
pub fn with_ai(mut self, generator: Arc<dyn AiGenerator + Send + Sync>) -> Self {
self.ai_generator = Some(generator);
self
}
pub fn with_mockai(mut self, mockai: Arc<RwLock<MockAI>>) -> Self {
self.mockai = Some(mockai);
self
}
pub fn with_mockai_opt(mut self, mockai: Option<Arc<RwLock<MockAI>>>) -> Self {
self.mockai = mockai;
self
}
pub fn smtp_registry(mut self, registry: Arc<dyn std::any::Any + Send + Sync>) -> Self {
self.smtp_registry = Some(registry);
self
}
pub fn smtp_registry_opt(
mut self,
registry: Option<Arc<dyn std::any::Any + Send + Sync>>,
) -> Self {
self.smtp_registry = registry;
self
}
pub fn mqtt_broker(mut self, broker: Arc<dyn std::any::Any + Send + Sync>) -> Self {
self.mqtt_broker = Some(broker);
self
}
pub fn mqtt_broker_opt(mut self, broker: Option<Arc<dyn std::any::Any + Send + Sync>>) -> Self {
self.mqtt_broker = broker;
self
}
pub fn with_traffic_shaping(mut self, shaper: TrafficShaper) -> Self {
self.traffic_shaper = Some(shaper);
self.traffic_shaping_enabled = true;
self
}
pub fn with_traffic_shaping_opt(
mut self,
shaper: Option<TrafficShaper>,
enabled: bool,
) -> Self {
self.traffic_shaper = shaper;
self.traffic_shaping_enabled = enabled;
self
}
pub fn with_chains(mut self, config: ChainConfig) -> Self {
self.chain_config = Some(config);
self
}
pub fn health_manager(mut self, manager: Arc<HealthManager>) -> Self {
self.health_manager = Some(manager);
self
}
pub fn health_manager_opt(mut self, manager: Option<Arc<HealthManager>>) -> Self {
self.health_manager = manager;
self
}
pub fn with_deceptive_deploy(mut self, config: DeceptiveDeployConfig) -> Self {
self.deceptive_deploy_config = Some(config);
self
}
pub fn with_deceptive_deploy_opt(mut self, config: Option<DeceptiveDeployConfig>) -> Self {
self.deceptive_deploy_config = config;
self
}
pub fn proxy_config(mut self, config: ProxyConfig) -> Self {
self.proxy_config = Some(config);
self
}
#[allow(deprecated)]
pub async fn build(self) -> Router {
crate::build_router_with_chains_and_multi_tenant(
self.spec_path,
self.validation_options,
self.chain_config,
self.multi_tenant_config,
self.route_configs,
self.cors_config,
self.ai_generator,
self.smtp_registry,
self.mqtt_broker,
self.traffic_shaper,
self.traffic_shaping_enabled,
self.health_manager,
self.mockai,
self.deceptive_deploy_config,
self.proxy_config,
)
.await
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_builder_default() {
let _router = HttpRouterBuilder::new().build().await;
}
#[tokio::test]
async fn test_builder_with_spec_path() {
let _router = HttpRouterBuilder::new()
.spec_path("/nonexistent/spec.yaml".to_string())
.build()
.await;
}
#[tokio::test]
async fn test_builder_default_impl() {
let _router = HttpRouterBuilder::default().build().await;
}
#[tokio::test]
async fn test_builder_chain_multiple_options() {
let _router = HttpRouterBuilder::new()
.spec_path_opt(None)
.validation_options_opt(None)
.with_multi_tenant_opt(None)
.route_configs_opt(None)
.cors_config_opt(None)
.with_mockai_opt(None)
.smtp_registry_opt(None)
.mqtt_broker_opt(None)
.with_traffic_shaping_opt(None, false)
.health_manager_opt(None)
.with_deceptive_deploy_opt(None)
.build()
.await;
}
}