<?php

declare(strict_types=1);

namespace App\Framework\Waf;

use App\Framework\Waf\Layers\MLEnhancedWafLayer;
use App\Framework\Waf\MachineLearning\BehaviorPatternExtractor;
use App\Framework\Waf\MachineLearning\BehaviorAnomalyDetector;
use App\Framework\Waf\MachineLearning\RequestHistoryTracker;
use App\Framework\Waf\MachineLearning\WafBehavioralModelAdapter;
use App\Framework\DI\Container;
use App\Framework\DI\Attributes\Initializer;
use App\Framework\Cache\Cache;
use App\Framework\Config\Environment;
use App\Framework\Core\ValueObjects\Score;
use App\Framework\MachineLearning\ModelManagement\ModelPerformanceMonitor;
use App\Framework\MachineLearning\ModelManagement\ModelRegistry;
use App\Framework\Infrastructure\GeoIp\GeoIp;
use Psr\Log\LoggerInterface;

/**
 * Initializer for ML-Enhanced WAF Layer
 *
 * Bootstraps the ML behavioral analysis layer and its dependencies
 */
final readonly class MLEnhancedWafLayerInitializer
{
    public function __construct(
        private Container $container,
        private Environment $environment,
        private LoggerInterface $logger
    ) {}

    #[Initializer]
    public function __invoke(Container $container): MLEnhancedWafLayer
    {
        // 1. Resolve dependencies
        $cache = $container->get(Cache::class);
        $geoIp = $container->get(GeoIp::class);
        $logger = $container->get(LoggerInterface::class);

        // 2. Create RequestHistoryTracker
        $historyTracker = new RequestHistoryTracker(
            cache: $cache,
            maxRequestsPerIp: 50,    // Last 50 requests per IP
            timeWindowSeconds: 300    // 5-minute sliding window
        );

        // 3. Create BehaviorPatternExtractor
        $patternExtractor = new BehaviorPatternExtractor(
            geoIp: $geoIp,
            minConfidence: 0.6
        );

        // 4. Create BehaviorAnomalyDetector
        $anomalyDetector = new BehaviorAnomalyDetector(
            anomalyThreshold: Score::medium(),  // 0.5 threshold
            zScoreThreshold: 3.0,               // 99.7% confidence interval
            iqrMultiplier: 1.5                   // Standard IQR multiplier
        );

        // 5. Create ML-Enhanced WAF Layer
        return new MLEnhancedWafLayer(
            historyTracker: $historyTracker,
            patternExtractor: $patternExtractor,
            anomalyDetector: $anomalyDetector,
            logger: $logger,
            confidenceThreshold: Score::medium(),  // Block at medium confidence
            minHistorySize: 5,                     // Need at least 5 requests for analysis
            enableStatisticalDetection: true       // Enable statistical baseline comparison
        );
    }

    /**
     * Initialize WAF Behavioral Model Adapter for ML Model Management integration
     */
    #[Initializer]
    public function initializeModelAdapter(): WafBehavioralModelAdapter
    {
        $this->logger->info('Initializing WAF Behavioral Model Adapter');

        try {
            // Get required dependencies from container
            $registry = $this->container->get(ModelRegistry::class);
            $performanceMonitor = $this->container->get(ModelPerformanceMonitor::class);
            $anomalyDetector = $this->container->get(BehaviorAnomalyDetector::class);

            $adapter = new WafBehavioralModelAdapter(
                registry: $registry,
                performanceMonitor: $performanceMonitor,
                detector: $anomalyDetector
            );

            // Auto-register current model version if enabled
            if ($this->environment->getBool('WAF_ML_AUTO_REGISTER', true)) {
                try {
                    $metadata = $adapter->registerCurrentModel();
                    $this->logger->info('WAF behavioral model auto-registered', [
                        'model_name' => $metadata->modelName,
                        'version' => $metadata->version->toString(),
                        'type' => $metadata->modelType->value,
                    ]);
                } catch (\Exception $e) {
                    // Model might already exist, which is fine
                    $this->logger->debug('WAF behavioral model registration skipped', [
                        'reason' => $e->getMessage(),
                    ]);
                }
            }

            $this->logger->info('WAF Behavioral Model Adapter initialized successfully');

            return $adapter;
        } catch (\Throwable $e) {
            $this->logger->error('Failed to initialize WAF Behavioral Model Adapter', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            throw $e;
        }
    }
}
