<?php

declare(strict_types=1);

namespace BotGuard\Tests\Unit;

use BotGuard\Core\Database;
use BotGuard\Models\Announcement;
use BotGuard\Models\ApiKey;
use BotGuard\Services\BackupService;
use PHPUnit\Framework\TestCase;

/**
 * Tests for the pure (DB-free) logic of the API-key, announcement and backup
 * features: key hashing/format, level validation and backup filename safety.
 */
final class AdminFeaturesTest extends TestCase
{
    public function testApiKeyHashIsDeterministicAndPrefixed(): void
    {
        $this->assertSame('bg_', ApiKey::PREFIX);
        $this->assertSame(hash('sha256', 'bg_abc'), ApiKey::hash('bg_abc'));
        $this->assertSame(64, strlen(ApiKey::hash('anything')));
    }

    public function testAnnouncementLevelValidation(): void
    {
        $this->assertTrue(Announcement::isValidLevel('warning'));
        $this->assertFalse(Announcement::isValidLevel('purple'));
        $this->assertSame(['info', 'success', 'warning', 'danger'], Announcement::LEVELS);
    }

    public function testBackupFilenameValidationRejectsTraversal(): void
    {
        // Database is constructed but never connected (path() does no queries).
        $service = new BackupService(new Database([
            'driver' => 'mysql', 'host' => '127.0.0.1', 'port' => 3306,
            'database' => 'x', 'username' => 'x', 'password' => '', 'charset' => 'utf8mb4', 'options' => [],
        ]));

        // Malicious / malformed names are rejected outright.
        $this->assertNull($service->path('../../etc/passwd'));
        $this->assertNull($service->path('backup-bad.sql'));
        $this->assertNull($service->path('backup-20260101-120000.sql.php'));

        // A well-formed name that exists resolves; cleanup afterwards.
        $dir = storage_path('backups');
        @mkdir($dir, 0775, true);
        $name = 'backup-20260101-120000.sql';
        file_put_contents($dir . DIRECTORY_SEPARATOR . $name, '-- test');

        $this->assertSame($dir . DIRECTORY_SEPARATOR . $name, $service->path($name));

        @unlink($dir . DIRECTORY_SEPARATOR . $name);
    }
}
