<?php

declare(strict_types=1);

use App\Framework\Core\ValueObjects\Duration;
use App\Framework\DateTime\SystemClock;
use App\Framework\DDoS\ValueObjects\DDoSAssessment;
use App\Framework\DDoS\ValueObjects\ThreatLevel;
use App\Framework\Http\Cookies\Cookies;
use App\Framework\Http\Headers;
use App\Framework\Http\HttpRequest;
use App\Framework\Http\IpAddress;
use App\Framework\Http\Method;
use App\Framework\Http\RequestBody;
use App\Framework\Http\RequestId;
use App\Framework\Http\ServerEnvironment;
use App\Framework\Http\UploadedFiles;

/**
 * Helper function to create test HTTP requests
 */
function createTestRequest(string $ip, string $method, string $path, array $headers = [], array $postData = [], array $cookies = []): HttpRequest
{
    $defaultHeaders = [
        'Host' => 'example.com',
        'User-Agent' => 'Mozilla/5.0 (compatible; TestClient/1.0)',
        'Accept' => 'text/html,application/json',
    ];

    $allHeaders = array_merge($defaultHeaders, $headers);

    $serverVars = [
        'REQUEST_METHOD' => $method,
        'REQUEST_URI' => $path,
        'SERVER_NAME' => 'example.com',
        'REMOTE_ADDR' => $ip,
        'HTTP_HOST' => 'example.com',
    ];

    foreach ($allHeaders as $name => $value) {
        $serverKey = 'HTTP_' . strtoupper(str_replace('-', '_', $name));
        $serverVars[$serverKey] = $value;
    }

    // Create HttpRequest using constructor
    return new HttpRequest(
        method: Method::from($method),
        headers: new Headers($allHeaders),
        body: ! empty($postData) ? json_encode($postData) : '',
        path: $path,
        queryParams: [],
        files: new UploadedFiles([]),
        cookies: new Cookies(),
        server: new ServerEnvironment($serverVars),
        id: new RequestId(),
        parsedBody: new RequestBody(
            Method::from($method),
            new Headers($allHeaders),
            ! empty($postData) ? json_encode($postData) : '',
            $postData
        )
    );
}

/**
 * Helper function to create test DDoS assessments
 */
function createThreatAssessment(ThreatLevel $threatLevel, float $confidence, array $attackPatterns = [], ?string $clientIp = null): DDoSAssessment
{
    $clock = new SystemClock();

    return new DDoSAssessment(
        threatLevel: $threatLevel,
        attackPatterns: $attackPatterns,
        clientIp: IpAddress::from($clientIp ?? '192.168.1.100'),
        analysisResults: ['threat_score' => $confidence],
        confidence: $confidence,
        recommendedAction: match($threatLevel) {
            ThreatLevel::LOW => 'allow',
            ThreatLevel::MEDIUM => 'rate_limit',
            ThreatLevel::HIGH => 'block',
            ThreatLevel::CRITICAL => 'block'
        },
        processingTime: Duration::fromMilliseconds(10),
        timestamp: $clock->time()
    );
}

/**
 * Helper function to create mock DDoS engine
 */
function createMockEngine(): object
{
    // In a real test, we'd use proper DI container setup
    // For now, return a basic mock that we can work with
    return new class () {
        public function assessRequest($request)
        {
            return createThreatAssessment(ThreatLevel::LOW, 0.1);
        }
    };
}

/**
 * Helper function to create engine with specific config
 */
function createEngineWithConfig($config): object
{
    // Factory method to create engine with specific config
    return new class ($config) {
        public function __construct(private $config)
        {
        }

        public function assessRequest($request)
        {
            if (! $this->config->enabled) {
                return createThreatAssessment(ThreatLevel::LOW, 0.0);
            }

            return createThreatAssessment(ThreatLevel::LOW, 0.1);
        }
    };
}
