"""Static guards for migration 191 (account_quota_overrides.unlimited).

Прод применяет data/sql построчно строго (ON_ERROR_STOP). Полный DB-прогон
требует живой БД; здесь фиксируем структурные инварианты, которые ГАРАНТИРУЮТ
идемпотентность и что миграция реально закрывает bootstrap unlimited-грантов
для kopylov (перенос хардкода из app.services.account_quota.is_unlimited) и
praktika (пилот восстановлен 2026-07-27).
"""

from __future__ import annotations

import re
from pathlib import Path

_SQL_DIR = Path(__file__).resolve().parents[1] / "data" / "sql"
_MIGRATION_191 = _SQL_DIR / "191_account_quota_unlimited_flag.sql"


def _sql() -> str:
    return _MIGRATION_191.read_text(encoding="utf-8")


def _executable_sql() -> str:
    """SQL без построчных `--`-комментариев — только исполняемый код."""
    lines = []
    for raw in _sql().splitlines():
        code = raw.split("--", 1)[0]
        if code.strip():
            lines.append(code)
    return "\n".join(lines)


def _flat(text: str) -> str:
    return re.sub(r"\s+", " ", text).strip().lower()


def test_migration_191_exists() -> None:
    assert _MIGRATION_191.exists(), f"missing migration: {_MIGRATION_191}"


def test_migration_191_is_transactional() -> None:
    sql = _sql()
    assert "BEGIN;" in sql
    assert "COMMIT;" in sql


def test_migration_191_adds_unlimited_column_idempotently() -> None:
    """ADD COLUMN IF NOT EXISTS — безопасен при повторном прогоне."""
    flat = _flat(_executable_sql())
    assert "alter table account_quota_overrides" in flat
    assert "add column if not exists unlimited boolean not null default false" in flat


def test_migration_191_seeds_kopylov_and_praktika_unlimited() -> None:
    """Оба грант-аккаунта присутствуют в seed-данных с unlimited=true."""
    flat = _flat(_executable_sql())
    assert "'kopylov'" in flat
    assert "'praktika'" in flat
    # Ровно 2 INSERT INTO account_quota_overrides в этом файле (kopylov + praktika).
    assert flat.count("insert into account_quota_overrides") == 2
    # unlimited=true передаётся позиционно в VALUES для обеих строк.
    assert flat.count("999999, true") == 2


def test_migration_191_seed_upserts_are_idempotent() -> None:
    """ON CONFLICT (username) DO UPDATE — повторный прогон сходится к тому же
    состоянию, не дублирует строки (username — PRIMARY KEY, см. migration 185)."""
    flat = _flat(_executable_sql())
    assert flat.count("on conflict (username) do update set") == 2
    assert "unlimited = excluded.unlimited" in flat


def test_migration_191_no_psycopg_trap() -> None:
    """Никаких :param::type — psycopg v3 требует CAST(... AS type) (не применимо
    в чистом .sql без bind params, но проверяем на регресс copy-paste)."""
    assert not re.search(r":\w+::", _sql())


def test_migration_191_no_destructive_ddl() -> None:
    """Миграция не должна содержать DROP TABLE / TRUNCATE (см. .claude/rules/sql.md)."""
    flat = _flat(_executable_sql())
    assert "drop table" not in flat
    assert "truncate" not in flat
