<?php

declare(strict_types=1);

namespace Tests\Unit;

use Exception;
use PDOException;
use PHPUnit\Framework\TestCase;

final class ErrorsTest extends TestCase
{
    protected function setUp(): void
    {
        require_once dirname(__DIR__, 2) . '/lib/errors.php';
    }

    public function testLockExceptionDetection(): void
    {
        $this->assertTrue(qdb_is_lock_exception(new Exception('Could not acquire lock')));
        $this->assertTrue(qdb_is_lock_exception(new Exception('Could not open lock file')));
        $this->assertFalse(qdb_is_lock_exception(new Exception('other')));
    }

    public function testPublicErrorMessageForLock(): void
    {
        $msg = qdb_public_error_message(new Exception('Could not acquire lock'), 'Save');
        $this->assertStringContainsString('busy', strtolower($msg));
    }

    public function testPublicErrorMessageForDecrypt(): void
    {
        $msg = qdb_public_error_message(new Exception('decrypt failed'), 'Open');
        $this->assertStringContainsString('configuration', strtolower($msg));
    }

    public function testPublicErrorMessageForPdo(): void
    {
        $msg = qdb_public_error_message(new PDOException('SQLITE_CONSTRAINT'), 'Query');
        $this->assertStringContainsString('database error', strtolower($msg));
    }

    public function testApiErrorForLockUses503(): void
    {
        [$code, , $status] = qdb_api_error_for_exception(new Exception('Could not acquire lock'), 'Write');
        $this->assertSame('LOCKED', $code);
        $this->assertSame(503, $status);
    }

    public function testApiErrorForGenericUses500(): void
    {
        [$code, , $status] = qdb_api_error_for_exception(new Exception('boom'), 'Op');
        $this->assertSame('SERVER_ERROR', $code);
        $this->assertSame(500, $status);
    }
}
