"""Тесты для app/core/password.py — bcrypt hash/verify (#2550)."""

from __future__ import annotations

import pytest

from app.core.password import hash_password, verify_password


def test_roundtrip() -> None:
    """hash_password → verify_password с тем же паролем возвращает True."""
    hashed = hash_password("correct horse battery staple")
    assert verify_password("correct horse battery staple", hashed) is True


def test_wrong_password_returns_false() -> None:
    """Неверный пароль против валидного хеша → False."""
    hashed = hash_password("correct horse battery staple")
    assert verify_password("wrong password", hashed) is False


def test_hash_too_long_raises_value_error() -> None:
    """Пароль >72 байт в UTF-8 → ValueError в hash_password (нет silent truncation)."""
    long_password = "a" * 73
    with pytest.raises(ValueError):
        hash_password(long_password)


def test_hash_exactly_72_bytes_ok() -> None:
    """Ровно 72 байта — граничное значение, ещё допустимо."""
    password = "a" * 72
    hashed = hash_password(password)
    assert verify_password(password, hashed) is True


def test_hash_too_long_multibyte_raises_value_error() -> None:
    """40 кириллических символов = 80 байт UTF-8 (2 байта/символ) → ValueError.

    Проверяет, что лимит считается в байтах, а не в символах — иначе 40-символьный
    кириллический пароль (< 72 символов, но 80 байт) прошёл бы мимо guard'а.
    """
    long_cyrillic_password = "а" * 40
    assert len(long_cyrillic_password.encode("utf-8")) == 80
    with pytest.raises(ValueError):
        hash_password(long_cyrillic_password)


def test_verify_too_long_returns_false_not_raise() -> None:
    """verify_password на >72-байтовом пароле возвращает False, НЕ raise."""
    hashed = hash_password("some valid password")
    long_password = "a" * 73
    assert verify_password(long_password, hashed) is False


def test_hash_empty_raises_value_error() -> None:
    """Пустой пароль → ValueError в hash_password."""
    with pytest.raises(ValueError):
        hash_password("")


def test_verify_empty_returns_false() -> None:
    """Пустой пароль в verify_password → False (не raise)."""
    hashed = hash_password("some valid password")
    assert verify_password("", hashed) is False


def test_hash_is_unique_due_to_salt() -> None:
    """Два хеша одного пароля различаются (уникальная соль на каждый вызов)."""
    password = "correct horse battery staple"
    hash1 = hash_password(password)
    hash2 = hash_password(password)
    assert hash1 != hash2
    assert verify_password(password, hash1) is True
    assert verify_password(password, hash2) is True


def test_verify_malformed_hash_returns_false() -> None:
    """Некорректный (не-bcrypt) хеш в verify_password → False, не raise."""
    assert verify_password("some password", "not-a-bcrypt-hash") is False
