<?php

namespace App\Tests\Shared;

use Doctrine\DBAL\Connection;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * The `logger` service is decorated by App\Shared\Logging\DbLogger, which persists
 * warning-and-above to the app_log table while leaving info/debug on stderr only.
 */
class DbLoggerTest extends KernelTestCase
{
    public function testWarningPersistedButInfoIsNot(): void
    {
        self::bootKernel();
        $c = static::getContainer();
        /** @var LoggerInterface $logger */
        $logger = $c->get('logger');
        /** @var Connection $conn */
        $conn = $c->get('doctrine.dbal.default_connection');

        $marker = 'DBLOGGER_TEST_' . bin2hex(random_bytes(5));

        $logger->info($marker . '_info');
        $logger->warning($marker . '_warn', ['exception' => new \RuntimeException('boom')]);

        $warn = (int) $conn->fetchOne('SELECT COUNT(*) FROM app_log WHERE message = ?', [$marker . '_warn']);
        $info = (int) $conn->fetchOne('SELECT COUNT(*) FROM app_log WHERE message = ?', [$marker . '_info']);

        self::assertSame(1, $warn, 'warning must be persisted to app_log');
        self::assertSame(0, $info, 'info must NOT be persisted to app_log');

        // The Throwable in context is stored as a compact string, not a raw object.
        $row = $conn->fetchAssociative('SELECT context, level, channel FROM app_log WHERE message = ?', [$marker . '_warn']);
        self::assertSame('warning', $row['level']);
        self::assertSame('app', $row['channel']);
        self::assertStringContainsString('RuntimeException: boom', (string) $row['context']);

        $conn->executeStatement('DELETE FROM app_log WHERE message LIKE ?', [$marker . '%']);
    }
}
