<?php

use routes\moduleScannerRoute;

app_require('routes/moduleScannerRoute.php');

it('returns no-plate LPR results without a failed HTTP status', function (): void {
    $route = file_get_contents(app_path('routes/moduleScannerRoute.php'));

    expect($route)->not->toBeFalse();
    expect($route)->toContain("'reason' => 'no_license_plate_detected'");
    expect($route)->toContain('], 200);');
    expect($route)->not->toContain("throw new Exception('License plate extraction failed.')");
});

it('returns low-confidence LPR results without a failed HTTP status', function (): void {
    $route = file_get_contents(app_path('routes/moduleScannerRoute.php'));

    expect($route)->not->toBeFalse();
    expect($route)->toContain("'reason' => 'low_confidence_license_plate'");
    expect($route)->toContain("'message' => 'License plate recognition confidence too low.'");
    expect($route)->toContain("'confidence' => \$lpr_result['confidence']");
    expect($route)->not->toContain('License plate recognition confidence too low. Score:');
    expect($route)->not->toContain('use Exception;');
});

it('does not store scanner images before LPR recognition', function (): void {
    $route = file_get_contents(app_path('routes/moduleScannerRoute.php'));

    expect($route)->not->toBeFalse();
    expect($route)->toContain('new licenseplaterecognizer(false)');
    expect($route)->toContain('getLPRImageUpload()');
    expect($route)->toContain('getLPRRawImageUpload()');
    expect($route)->toContain('$base64_image = null;');
    expect($route)->toContain('if ($image_upload === null && $raw_image_upload === null)');
    expect($route)->toContain('licenseplaterecognizerUploadFile($image_upload');
    expect($route)->toContain('licenseplaterecognizerUploadUncached($raw_image_upload');
    expect($route)->toContain("'path' => \$tmp_name");
    expect($route)->toContain("'data' => \$image_data");
    expect($route)->toContain("file_get_contents('php://input')");
    expect($route)->toContain("str_starts_with(\$mime_type, 'image/')");
    expect($route)->toContain('$recognizer->licenseplaterecognizer((string)$base64_image)');
    expect($route)->toContain('$route_started_at = microtime(true);');
    expect($route)->toContain('$client_timings = self::getLPRClientTimings();');
    expect($route)->toContain('array_merge($client_timings, $recognizer->getLastTimings())');
    expect($route)->toContain("header('Server-Timing: '");
    expect($route)->toContain("'client_capture'");
    expect($route)->toContain("'client_preflight'");
    expect($route)->toContain("'client_visual_fingerprint'");
    expect($route)->toContain("'client_draw'");
    expect($route)->toContain("'client_encode'");
    expect($route)->toContain("'client_frame_width'");
    expect($route)->toContain("'client_frame_height'");
    expect($route)->toContain("'client_frame_bytes'");
    expect($route)->toContain("'cache'");
    expect($route)->toContain("'cache_hit'");
    expect($route)->toContain("'cache_miss'");
    expect($route)->toContain("\$timings['local'] = self::getLPRLocalDuration(\$timings);");
    expect($route)->toContain("'local'");
    expect($route)->toContain("'upstream_dns'");
    expect($route)->toContain("'upstream_connect'");
    expect($route)->toContain("'upstream_tls'");
    expect($route)->toContain("'upstream_pretransfer'");
    expect($route)->toContain("'upstream_ttfb'");
    expect($route)->toContain("'upstream_total'");
    expect($route)->toContain("'upstream_processing'");
    expect($route)->toContain("'route_total'");
    expect($route)->toContain("'request_total'");
    expect($route)->toContain('HTTP_X_LPR_CLIENT_CAPTURE_MS');
    expect($route)->toContain('HTTP_X_LPR_CLIENT_FRAME_BYTES');
    expect($route)->toContain('$value = $_GET[$field] ?? null;');
    expect($route)->toContain("isset(\$_SERVER['REQUEST_TIME_FLOAT'])");
    expect($route)->not->toContain("requireParameters(['base64_image'])");
    expect($route)->not->toContain('file_get_contents($tmp_name)');
    expect($route)->not->toContain('storeTempImageFromBase64');
    expect($route)->not->toContain('new upload_store');
    expect($route)->not->toContain('new openai');
});

it('reads raw scanner client timing metadata from request query parameters', function (): void {
    $previousGet = $_GET;
    $previousPost = $_POST;
    $headerNames = [
        'HTTP_X_LPR_CLIENT_CAPTURE_MS',
        'HTTP_X_LPR_CLIENT_PREFLIGHT_MS',
        'HTTP_X_LPR_CLIENT_DRAW_MS',
        'HTTP_X_LPR_CLIENT_ENCODE_MS',
        'HTTP_X_LPR_CLIENT_VISUAL_FINGERPRINT_MS',
        'HTTP_X_LPR_CLIENT_FRAME_WIDTH',
        'HTTP_X_LPR_CLIENT_FRAME_HEIGHT',
        'HTTP_X_LPR_CLIENT_FRAME_BYTES',
    ];
    $previousHeaders = [];
    foreach ($headerNames as $headerName) {
        $previousHeaders[$headerName] = $_SERVER[$headerName] ?? null;
    }

    try {
        $_GET = [
            'client_capture_ms' => '12.345',
            'client_preflight_ms' => '1.500',
            'client_draw_ms' => '2.250',
            'client_encode_ms' => '8.500',
            'client_visual_fingerprint_ms' => '0.750',
            'client_frame_width' => '384',
            'client_frame_height' => '216',
            'client_frame_bytes' => '12345',
        ];
        $_POST = [];

        $reflection = new ReflectionClass(moduleScannerRoute::class);
        $method = $reflection->getMethod('getLPRClientTimings');

        expect($method->invoke(null))->toMatchArray([
            'client_capture' => 12.345,
            'client_preflight' => 1.5,
            'client_draw' => 2.25,
            'client_encode' => 8.5,
            'client_visual_fingerprint' => 0.75,
            'client_frame_width' => 384.0,
            'client_frame_height' => 216.0,
            'client_frame_bytes' => 12345.0,
        ]);
    } finally {
        $_GET = $previousGet;
        $_POST = $previousPost;
        foreach ($previousHeaders as $headerName => $previousValue) {
            if ($previousValue === null) {
                unset($_SERVER[$headerName]);
            } else {
                $_SERVER[$headerName] = $previousValue;
            }
        }
    }
});
