<?php

declare(strict_types=1);

namespace Tests\Security\WafTests;

use Tests\Security\SecurityTestCase;
use App\Framework\Waf\WafEngine;
use App\Framework\Http\Method;

/**
 * Command Injection attack detection tests
 *
 * Tests WAF's ability to detect and block command injection attacks
 */
final readonly class CommandInjectionTest extends SecurityTestCase
{
    public function __construct(
        private WafEngine $wafEngine
    ) {}

    /**
     * Test WAF blocks command injection attempts
     */
    public function testBlocksCommandInjection(): void
    {
        $testCases = $this->generateCommandInjectionTestCases();
        $blocked = 0;
        $failed = [];

        foreach ($testCases as $testCase) {
            $request = $this->createAttackRequest(
                uri: '/api/execute',
                method: Method::POST,
                postData: ['command' => $testCase['payload']]
            );

            $decision = $this->wafEngine->analyzeRequest($request);

            if ($decision->shouldBlock()) {
                $blocked++;
            } else {
                $failed[] = $testCase['description'];
            }
        }

        if (!empty($failed)) {
            throw new \RuntimeException(
                "WAF failed to block " . count($failed) . " command injection attacks:\n" .
                implode("\n", array_slice($failed, 0, 5))
            );
        }

        echo "✅ Blocked {$blocked}/" . count($testCases) . " command injection attacks\n";
    }

    /**
     * Run all command injection tests
     */
    public function runAllTests(): array
    {
        $results = [];

        try {
            $this->testBlocksCommandInjection();
            $results['command_injection'] = 'PASS';
        } catch (\Exception $e) {
            $results['command_injection'] = 'FAIL: ' . $e->getMessage();
        }

        return $results;
    }
}
