use super::config::*;
use super::state::*;
use crate::OptimizerError as OptimError;
use scirs2_core::numeric::Float;
use std::collections::{HashMap, VecDeque};
use std::fmt::Debug;
use std::time::{Duration, SystemTime};
use super::types::{ApiClientConfig, ApiRequest, ApiResponse, ConflictResolutionResult, ConnectorConfig, ConsumerConfig, DataConflict, Event, EventPriority, ExternalData, FilterConfig, HealthStatus, IntegrationConfig, IntegrationManager, Message, PoolSettings, ProducerConfig, RetryConfig, RetryStrategy, Webhook, WebhookRequest, WebhookResponse};
type Result<T> = std::result::Result<T, OptimError>;
pub trait ExternalConnector<
T: Float + Debug + Send + Sync + 'static,
>: Send + Sync + Debug {
fn connect(&mut self) -> Result<()>;
fn disconnect(&mut self) -> Result<()>;
fn is_connected(&self) -> bool;
fn send_data(&mut self, data: &ExternalData<T>) -> Result<()>;
fn receive_data(&mut self) -> Result<Option<ExternalData<T>>>;
fn get_config(&self) -> ConnectorConfig;
fn update_config(&mut self, config: ConnectorConfig) -> Result<()>;
fn name(&self) -> &str;
fn health_check(&self) -> Result<HealthStatus>;
}
pub trait ApiClient<T: Float + Debug + Send + Sync + 'static>: Send + Sync + Debug {
fn get(
&self,
endpoint: &str,
params: &HashMap<String, String>,
) -> Result<ApiResponse<T>>;
fn post(&self, endpoint: &str, data: &ApiRequest<T>) -> Result<ApiResponse<T>>;
fn put(&self, endpoint: &str, data: &ApiRequest<T>) -> Result<ApiResponse<T>>;
fn delete(
&self,
endpoint: &str,
params: &HashMap<String, String>,
) -> Result<ApiResponse<T>>;
fn get_config(&self) -> ApiClientConfig;
fn update_config(&mut self, config: ApiClientConfig) -> Result<()>;
fn name(&self) -> &str;
fn authenticate(&mut self) -> Result<()>;
fn is_authenticated(&self) -> bool;
}
pub trait DataFilter<T: Float + Debug + Send + Sync + 'static>: Send + Sync + Debug {
fn should_sync(&self, data: &ExternalData<T>) -> bool;
fn transform(&self, data: ExternalData<T>) -> Result<ExternalData<T>>;
fn name(&self) -> &str;
}
pub trait ConflictResolver<
T: Float + Debug + Send + Sync + 'static,
>: Send + Sync + Debug {
fn resolve(&self, conflict: &DataConflict<T>) -> Result<ConflictResolutionResult<T>>;
fn name(&self) -> &str;
fn can_resolve(&self, conflict: &DataConflict<T>) -> bool;
}
pub trait EventHandler<T: Float + Debug + Send + Sync + 'static>: Send + Sync + Debug {
fn handle(&mut self, event: &Event<T>) -> Result<()>;
fn name(&self) -> &str;
fn can_handle(&self, event: &Event<T>) -> bool;
fn priority(&self) -> EventPriority;
}
pub trait EventFilter<T: Float + Debug + Send + Sync + 'static>: Send + Sync + Debug {
fn filter(&self, event: &Event<T>) -> bool;
fn name(&self) -> &str;
fn config(&self) -> FilterConfig;
}
pub trait WebhookHandler<T: Float + Debug + Send + Sync + 'static>: Send + Sync + Debug {
fn handle_webhook(&mut self, request: &WebhookRequest<T>) -> Result<WebhookResponse>;
fn name(&self) -> &str;
fn validate_signature(&self, request: &WebhookRequest<T>) -> Result<bool>;
}
pub trait MessageProducer<
T: Float + Debug + Send + Sync + 'static,
>: Send + Sync + Debug {
fn send(&mut self, queue: &str, message: &Message<T>) -> Result<String>;
fn send_batch(
&mut self,
queue: &str,
messages: &[Message<T>],
) -> Result<Vec<String>>;
fn name(&self) -> &str;
fn config(&self) -> ProducerConfig;
}
pub trait MessageConsumer<
T: Float + Debug + Send + Sync + 'static,
>: Send + Sync + Debug {
fn receive(&mut self, queue: &str) -> Result<Option<Message<T>>>;
fn receive_batch(
&mut self,
queue: &str,
max_messages: usize,
) -> Result<Vec<Message<T>>>;
fn acknowledge(&mut self, message_id: &str) -> Result<()>;
fn reject(&mut self, message_id: &str, requeue: bool) -> Result<()>;
fn name(&self) -> &str;
fn config(&self) -> ConsumerConfig;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_integration_manager_creation() {
let config = IntegrationConfig::default();
let manager = IntegrationManager::<f32>::new(config);
assert!(manager.config.enabled);
assert_eq!(manager.connectors.len(), 0);
assert_eq!(manager.api_clients.len(), 0);
}
#[test]
fn test_retry_config() {
let config = RetryConfig::default();
assert_eq!(config.max_attempts, 3);
assert_eq!(config.strategy, RetryStrategy::ExponentialBackoff);
assert!(config.retriable_errors.contains(& 500));
}
#[test]
fn test_pool_settings() {
let settings = PoolSettings::default();
assert_eq!(settings.max_connections, 10);
assert_eq!(settings.min_connections, 1);
assert!(settings.connection_timeout > Duration::from_secs(0));
}
#[test]
fn test_event_priority_ordering() {
assert!(EventPriority::Emergency > EventPriority::Critical);
assert!(EventPriority::Critical > EventPriority::High);
assert!(EventPriority::High > EventPriority::Normal);
assert!(EventPriority::Normal > EventPriority::Low);
}
}