<?php

declare(strict_types=1);

use App\Framework\Logging\LogLevel;
use App\Framework\Logging\LogRecord;
use App\Framework\Logging\Processors\WebInfoProcessor;
use App\Framework\Logging\ValueObjects\LogContext;

describe('WebInfoProcessor', function () {
    beforeEach(function () {
        $this->timestamp = new DateTimeImmutable('2024-01-15 10:30:45', new DateTimeZone('Europe/Berlin'));
        $this->processor = new WebInfoProcessor();
    });

    describe('constructor', function () {
        it('can be instantiated with default config', function () {
            $processor = new WebInfoProcessor();

            expect($processor instanceof WebInfoProcessor)->toBeTrue();
        });

        it('can be instantiated with custom config', function () {
            $processor = new WebInfoProcessor([
                'url' => false,
                'ip' => true,
                'http_method' => true,
                'user_agent' => false,
                'referrer' => true
            ]);

            expect($processor instanceof WebInfoProcessor)->toBeTrue();
        });
    });

    describe('getPriority()', function () {
        it('returns priority 5', function () {
            expect($this->processor->getPriority())->toBe(5);
        });
    });

    describe('getName()', function () {
        it('returns name web_info', function () {
            expect($this->processor->getName())->toBe('web_info');
        });
    });

    describe('processRecord()', function () {
        it('returns record unchanged in CLI context', function () {
            // PHP_SAPI is 'cli' in tests
            $record = new LogRecord(
                message: 'Test message',
                context: LogContext::empty(),
                level: LogLevel::INFO,
                timestamp: $this->timestamp
            );

            $processed = $this->processor->processRecord($record);

            expect($processed->getExtras())->toBeEmpty();
        });

        it('adds web info when $_SERVER variables are set', function () {
            // Skip if PHP_SAPI is 'cli' (which it is in tests)
            if (PHP_SAPI === 'cli') {
                expect(true)->toBeTrue();
                return;
            }

            // This test would run in web context
            $_SERVER['REQUEST_URI'] = '/test/path';
            $_SERVER['REMOTE_ADDR'] = '192.168.1.1';
            $_SERVER['REQUEST_METHOD'] = 'GET';
            $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0';

            $processor = new WebInfoProcessor();

            $record = new LogRecord(
                message: 'Test',
                context: LogContext::empty(),
                level: LogLevel::INFO,
                timestamp: $this->timestamp
            );

            $processed = $processor->processRecord($record);

            $extras = $processed->getExtras();
            expect(isset($extras['url']))->toBeTrue();
            expect(isset($extras['ip']))->toBeTrue();
            expect(isset($extras['http_method']))->toBeTrue();
            expect(isset($extras['user_agent']))->toBeTrue();
        });

        it('respects config for disabling specific info', function () {
            if (PHP_SAPI === 'cli') {
                expect(true)->toBeTrue();
                return;
            }

            $processor = new WebInfoProcessor([
                'url' => false,
                'ip' => true,
                'http_method' => false,
                'user_agent' => true
            ]);

            $_SERVER['REQUEST_URI'] = '/test';
            $_SERVER['REMOTE_ADDR'] = '192.168.1.1';
            $_SERVER['REQUEST_METHOD'] = 'POST';
            $_SERVER['HTTP_USER_AGENT'] = 'TestAgent';

            $record = new LogRecord(
                message: 'Test',
                context: LogContext::empty(),
                level: LogLevel::INFO,
                timestamp: $this->timestamp
            );

            $processed = $processor->processRecord($record);

            $extras = $processed->getExtras();
            expect(isset($extras['url']))->toBeFalse();
            expect(isset($extras['ip']))->toBeTrue();
            expect(isset($extras['http_method']))->toBeFalse();
            expect(isset($extras['user_agent']))->toBeTrue();
        });
    });

    describe('configuration options', function () {
        it('can enable referrer collection', function () {
            $processor = new WebInfoProcessor([
                'referrer' => true
            ]);

            expect($processor instanceof WebInfoProcessor)->toBeTrue();
        });

        it('merges custom config with defaults', function () {
            // Test that partial config works
            $processor = new WebInfoProcessor([
                'user_agent' => false
            ]);

            expect($processor instanceof WebInfoProcessor)->toBeTrue();
        });
    });

    describe('readonly behavior', function () {
        it('is a final class', function () {
            $reflection = new ReflectionClass(WebInfoProcessor::class);

            expect($reflection->isFinal())->toBeTrue();
        });
    });
});
