<?php

declare(strict_types=1);

// Guard против повторения инцидента входа 26.06.2026 (см. db/CHANGELOG_schema.md v8.57).
//
// На Yandex Managed PG (PgBouncer transaction pooling) GUC app.current_tenant_id на
// пуло-соединении бывает пуст ('') или не задан. Прямое приведение
//   current_setting('app.current_tenant_id'[, true])::bigint
// падает: '' → 22P02 (invalid bigint), не задан → 42704 (unrecognized parameter).
// Это роняло вход (резолв users до tenant-контекста). Канон — всегда:
//   NULLIF(current_setting('app.current_tenant_id', true), '')::bigint
// Любое прямое приведение в db/ снова сломает вход. Тест статический (без БД).

it('в schema.sql нет небезопасного current_setting(app.current_tenant_id)::bigint (только через NULLIF)', function () {
    // Канон для пересборки БД — db/schema.sql (psql -f). Он ОБЯЗАН быть чистым.
    // Старые миграции — неизменяемая история; их небезопасные политики пересоздаёт
    // hardening-миграция 2026_06_26_153000 (итог migrate:fresh безопасен), поэтому
    // их здесь не сканируем — иначе ложные срабатывания на superseded-истории.
    //
    // Прямое приведение current_setting(...)::bigint без обёртки NULLIF.
    // Безопасная форма NULLIF(current_setting(...), '')::bigint этому НЕ соответствует:
    // там после current_setting(...) идёт ", ''", а не "::bigint".
    $unsafe = "/current_setting\\(\\s*'app\\.current_tenant_id'[^)]*\\)\\s*::\\s*bigint/i";

    $offenders = [];
    $lines = file(base_path('..').'/db/schema.sql', FILE_IGNORE_NEW_LINES) ?: [];
    foreach ($lines as $i => $line) {
        if (str_starts_with(ltrim($line), '--')) {
            continue; // строки-комментарии (документация) — не код политики
        }
        if (preg_match($unsafe, $line)) {
            $offenders[] = 'schema.sql:'.($i + 1).' → '.trim($line);
        }
    }

    expect($offenders)->toBe(
        [],
        'Небезопасное приведение GUC к bigint (без NULLIF) в schema.sql вернёт инцидент входа на Managed PG/PgBouncer:'
        .PHP_EOL.implode(PHP_EOL, $offenders)
    );
});

it('5 bootstrap-таблиц в schema.sql сохраняют ветку "NULLIF(...) IS NULL OR ..."', function () {
    $schema = file_get_contents(base_path('..').'/db/schema.sql');
    expect($schema)->not->toBeFalse();

    foreach (['users', 'auth_log', 'email_verifications', 'user_recovery_codes', 'user_sessions'] as $table) {
        // В пределах одного CREATE POLICY ... ON <table> ... ; должно быть условие
        // NULLIF(current_setting('app.current_tenant_id', true), '') IS NULL.
        $pattern = '/POLICY tenant_isolation ON '.preg_quote($table, '/')
            ."\\b[^;]*?NULLIF\\(current_setting\\('app\\.current_tenant_id', true\\), ''\\)\\s*IS NULL/s";
        expect((bool) preg_match($pattern, $schema))->toBeTrue(
            "Таблица {$table} должна иметь bootstrap-ветку «NULLIF(...) IS NULL OR ...» "
            .'(резолв до tenant-контекста на auth-роутах). Иначе вход/2FA/подтверждение почты сломаются.'
        );
    }
});
