<?php

declare(strict_types=1);

use App\Framework\Logging\LogLevel;
use App\Framework\Logging\ValueObjects\LogViewerConfig;

describe('LogViewerConfig', function () {
    it('creates valid config', function () {
        $config = new LogViewerConfig(
            storageLogsPath: '/var/www/html/storage/logs',
            logDirectories: ['app', 'debug'],
            defaultLimit: 100
        );

        expect($config->storageLogsPath)->toBe('/var/www/html/storage/logs');
        expect($config->logDirectories)->toBe(['app', 'debug']);
        expect($config->defaultLimit)->toBe(100);
        expect($config->logLevels)->toBeArray();
    });

    it('creates default config', function () {
        $config = LogViewerConfig::createDefault();

        expect($config->storageLogsPath)->toBe('/var/www/html/storage/logs');
        expect($config->logDirectories)->toContain('app');
        expect($config->logDirectories)->toContain('debug');
        expect($config->logDirectories)->toContain('security');
        expect($config->defaultLimit)->toBe(100);
    });

    it('creates development config', function () {
        $config = LogViewerConfig::createForDevelopment();

        expect($config->storageLogsPath)->toBe('/var/www/html/storage/logs');
        expect($config->logDirectories)->toContain('performance');
        expect($config->defaultLimit)->toBe(500);
        expect($config->logLevels)->toHaveCount(8); // All log levels
    });

    it('throws on invalid default limit', function () {
        new LogViewerConfig(
            storageLogsPath: '/var/www/html/storage/logs',
            logDirectories: ['app'],
            defaultLimit: 0
        );
    })->throws(\InvalidArgumentException::class, 'Default limit must be at least 1');

    it('throws on empty log directories', function () {
        new LogViewerConfig(
            storageLogsPath: '/var/www/html/storage/logs',
            logDirectories: [],
            defaultLimit: 100
        );
    })->throws(\InvalidArgumentException::class, 'At least one log directory must be specified');

    it('throws on empty log levels', function () {
        new LogViewerConfig(
            storageLogsPath: '/var/www/html/storage/logs',
            logDirectories: ['app'],
            defaultLimit: 100,
            logLevels: []
        );
    })->throws(\InvalidArgumentException::class, 'At least one log level must be specified');

    it('builds subdirectory path', function () {
        $config = LogViewerConfig::createDefault();

        $subdirPath = $config->getSubdirectoryPath('app');

        expect($subdirPath)->toBe('/var/www/html/storage/logs/app');
    });

    it('checks log level existence', function () {
        $config = LogViewerConfig::createDefault();

        expect($config->hasLogLevel(LogLevel::ERROR))->toBeTrue();
        expect($config->hasLogLevel(LogLevel::DEBUG))->toBeTrue();
    });

    it('gets log level names', function () {
        $config = LogViewerConfig::createDefault();

        $levelNames = $config->getLogLevelNames();

        expect($levelNames)->toBeArray();
        expect($levelNames)->toContain('ERROR');
        expect($levelNames)->toContain('DEBUG');
        expect($levelNames)->toContain('INFO');
    });

    it('accepts custom log levels', function () {
        $config = new LogViewerConfig(
            storageLogsPath: '/var/www/html/storage/logs',
            logDirectories: ['app'],
            defaultLimit: 100,
            logLevels: [LogLevel::ERROR, LogLevel::CRITICAL]
        );

        expect($config->hasLogLevel(LogLevel::ERROR))->toBeTrue();
        expect($config->hasLogLevel(LogLevel::CRITICAL))->toBeTrue();
        expect($config->hasLogLevel(LogLevel::DEBUG))->toBeFalse();
    });
});
