pub mod api;
pub mod core;
pub mod db;
pub mod security;
pub mod utils;
use actix_web::{web, App, HttpServer};
use config::Config;
use config::Environment;
use maxminddb::Reader;
use mysql_async::Pool;
use secrecy::SecretVec;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use crate::core::behavior_bio::{BehaviorEngine, DefaultAnomalyDetector, DefaultBehavioralModel};
use crate::core::cross_location::{CrossValidationEngine, DefaultScoringStrategy};
use crate::core::device_fp::{
AdaptiveFingerprintEngine, DefaultAiProcessor as FpAiProcessor, DefaultQuantumEngine,
DefaultSecurityMonitor,
};
use crate::core::geo_resolver::{DefaultAiModel as GeoAiModel, DefaultBlockchain, GeoResolver};
use crate::core::network_analyzer::NetworkAnalyzer;
use crate::core::sensors_analyzer::SensorsAnalyzerEngine;
pub struct AppState {
pub x_engine: Arc<CrossValidationEngine>,
pub db_pool: Option<Pool>,
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let settings = Config::builder()
.add_source(Environment::default())
.build()
.unwrap();
let api_key: String = settings.get_string("API_KEY").expect("API_KEY not set");
let database_url = std::env::var("DATABASE_URL").ok();
let db_pool = if let Some(url) = database_url {
Some(Pool::new(mysql_async::Opts::from_url(&url).unwrap()))
} else {
println!("⚠️ لم يتم ضبط DATABASE_URL. سيعمل التطبيق في وضع التطوير (بدون قاعدة بيانات).");
None
};
println!("🔧 Initializing application engines...");
let geo_reader: Arc<crate::core::geo_resolver::GeoReaderEnum> = if db_pool.is_some() {
let geo_db_bytes = hex::decode("4d4d44425f434954590000000000000002000000000000000c000000636f756e747279000700000049534f5f434f44450000").expect("Failed to decode mock geo DB");
Arc::new(crate::core::geo_resolver::GeoReaderEnum::Real(
Reader::from_source(geo_db_bytes).expect("Failed to create geo DB reader"),
))
} else {
println!(
"[DEV MODE] لن يتم تحميل قاعدة بيانات MaxMind geo DB. سيتم استخدام كائن وهمي عبر Enum."
);
Arc::new(crate::core::geo_resolver::GeoReaderEnum::Mock(
crate::core::geo_resolver::MockGeoReader::new(),
))
};
let geo_resolver = Arc::new(GeoResolver::new(
SecretVec::new(vec![1; 32]),
Arc::new(GeoAiModel),
Arc::new(DefaultBlockchain),
true,
false,
geo_reader.clone(),
));
let fp_engine = Arc::new(AdaptiveFingerprintEngine::new(
Arc::new(DefaultSecurityMonitor::new()),
Arc::new(DefaultQuantumEngine::new().expect("Failed to create quantum engine")),
Arc::new(FpAiProcessor),
Arc::new(RwLock::new(HashMap::new())),
));
let behavior_engine = Arc::new(BehaviorEngine::new(
Arc::new(DefaultBehavioralModel),
Arc::new(DefaultAnomalyDetector {
max_speed_kmh: 1200.0,
}),
10,
));
let scoring_strategy = Arc::new(DefaultScoringStrategy {
location_weight: 0.4,
fingerprint_weight: 0.3,
behavior_weight: 0.3,
});
let sensors_engine = Arc::new(SensorsAnalyzerEngine::new(
SecretVec::new(vec![42; 48]),
Arc::new(crate::core::sensors_analyzer::DefaultSensorAnomalyDetector::default()),
));
let proxy_db = Arc::new(RwLock::new(
crate::core::network_analyzer::ProxyDatabase::default(),
));
let network_engine = Arc::new(NetworkAnalyzer::new(
SecretVec::new(vec![42; 32]),
proxy_db,
geo_reader.clone(),
Arc::new(crate::core::network_analyzer::DefaultAiNetworkAnalyzer),
));
let x_engine = Arc::new(CrossValidationEngine::new(
geo_resolver,
fp_engine,
behavior_engine,
sensors_engine,
network_engine,
scoring_strategy,
SecretVec::new(b"a_very_secret_final_verdict_key".to_vec()),
));
let app_state = web::Data::new(AppState {
x_engine: Arc::clone(&x_engine),
db_pool,
});
println!("✅ Engines initialized successfully.");
println!("🚀 Server starting at http://127.0.0.1:8080");
HttpServer::new(move || {
App::new()
.app_data(app_state.clone())
.configure(api::config)
})
.bind("127.0.0.1:8080")?
.run()
.await
}