<?php

declare(strict_types=1);

namespace App\Framework\DDoS\Components;

use App\Framework\DDoS\Waf\DDoSWafLayer;
use App\Framework\Http\HttpRequest;
use App\Framework\Logging\Logger;
use App\Framework\Waf\WafEngine;

/**
 * Adapter for WAF analysis in DDoS protection context
 *
 * This component provides a unified interface for WAF analysis,
 * supporting both the general WafEngine and the specialized DDoSWafLayer.
 */
final readonly class WafAnalysisAdapter
{
    public function __construct(
        private WafEngine     $wafEngine,
        private ?DDoSWafLayer $ddosWafLayer = null,
        private ?Logger        $logger = null,
    ) {
    }

    /**
     * Analyze request using WAF components
     *
     * @param HttpRequest $request The HTTP request to analyze
     * @return array Analysis results with threat assessment and confidence
     */
    public function analyzeRequest(HttpRequest $request): array
    {
        $results = [];

        // First, use the general WAF engine
        $wafResult = $this->wafEngine->analyzeRequest($request);
        $results['general_waf'] = $wafResult;

        // If available, also use the specialized DDoS WAF layer
        if ($this->ddosWafLayer !== null) {
            try {
                $ddosWafResult = $this->ddosWafLayer->process($request);
                $results['ddos_waf'] = $ddosWafResult;

                // Combine results for a more comprehensive analysis
                $combinedThreatLevel = $this->combineThreatLevels(
                    $wafResult->getThreatAssessment()->getThreatLevel()->value,
                    $ddosWafResult->getThreatLevel()
                );

                $this->logger->debug('Combined WAF analysis', [
                    'general_waf_threat' => $wafResult->getThreatAssessment()->getThreatLevel()->value,
                    'ddos_waf_threat' => $ddosWafResult->getThreatLevel(),
                    'combined_threat' => $combinedThreatLevel,
                ]);

                return [
                    'threat_score' => $combinedThreatLevel / 100.0,
                    'confidence' => 0.95, // High confidence with both WAF components
                    'results' => $results,
                ];
            } catch (\Throwable $e) {
                $this->logger->warning('Error in DDoS WAF layer', [
                    'error' => $e->getMessage(),
                ]);
            }
        }

        // If DDoS WAF layer is not available or failed, use only general WAF
        $threatLevel = $wafResult->getThreatAssessment()->getThreatLevel()->value;

        return [
            'threat_score' => $threatLevel / 100.0,
            'confidence' => 0.85, // Good confidence with general WAF only
            'results' => $results,
        ];
    }

    /**
     * Combine threat levels from different WAF components
     *
     * @param int $generalThreatLevel Threat level from general WAF (0-100)
     * @param int $ddosThreatLevel Threat level from DDoS WAF (0-100)
     * @return int Combined threat level (0-100)
     */
    private function combineThreatLevels(int $generalThreatLevel, int $ddosThreatLevel): int
    {
        // Weight DDoS WAF higher for DDoS-specific threats
        $weightedAverage = ($generalThreatLevel * 0.4) + ($ddosThreatLevel * 0.6);

        // Take the maximum if either is very high (>80)
        if ($generalThreatLevel > 80 || $ddosThreatLevel > 80) {
            return max($generalThreatLevel, $ddosThreatLevel);
        }

        return (int)$weightedAverage;
    }
}
