"""Тесты для Validator.JSON"""
import pytest


class TestJSONValidator:
    """Тесты JSON валидатора"""

    @pytest.fixture
    def sample_data(self):
        return {
            "user": {
                "id": 123,
                "username": "john_doe",
                "email": "john@example.com",
                "active": True,
                "banned": False,
                "age": 25,
                "role": "admin",
                "balance": None,
            },
            "posts": [
                {"id": 1, "likes": 42, "published": True},
                {"id": 2, "likes": 15, "published": False},
            ],
        }

    # ========== Проверка наличия/отсутствия ==========

    def test_validate_field_exists(self, sample_data):
        """Проверка наличия поля"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.email", exists=True) is True

    def test_validate_field_not_exists(self, sample_data):
        """Проверка отсутствия поля"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.missing", exists=False) is True

    def test_validate_missing_field_exists_false(self, sample_data):
        """Несуществующее поле не проходит exists=True"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.missing", exists=True) is False

    # ========== Проверка значений ==========

    def test_validate_boolean_true(self, sample_data):
        """Проверка булева значения True"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.active", value=True) is True

    def test_validate_boolean_false(self, sample_data):
        """Проверка булева значения False"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.banned", value=False) is True

    def test_validate_null_value(self, sample_data):
        """Проверка null значения"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.balance", value=None) is True

    def test_validate_string_value(self, sample_data):
        """Проверка строкового значения"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.role", value="admin") is True

    def test_validate_wrong_value(self, sample_data):
        """Неправильное значение не проходит"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.role", value="guest") is False

    # ========== Проверка типов ==========

    def test_validate_type_int(self, sample_data):
        """Проверка типа int"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.age", is_type=int) is True

    def test_validate_type_str(self, sample_data):
        """Проверка типа str"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.username", is_type=str) is True

    def test_validate_type_bool(self, sample_data):
        """Проверка типа bool"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.active", is_type=bool) is True

    def test_validate_wrong_type(self, sample_data):
        """Неправильный тип не проходит"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.age", is_type=str) is False

    # ========== Проверка диапазона ==========

    def test_validate_range_valid(self, sample_data):
        """Значение в диапазоне проходит"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.age", range_value=(18, 100)) is True

    def test_validate_range_invalid(self, sample_data):
        """Значение вне диапазона не проходит"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.age", range_value=(30, 100)) is False

    def test_validate_range_boundary(self, sample_data):
        """Граничное значение диапазона"""
        from utils.json_path import Validator

        assert Validator.JSON(sample_data, "$.user.age", range_value=(25, 30)) is True

    # ========== Проверка regex ==========

    def test_validate_regex_match(self, sample_data):
        """Regex совпадает"""
        from utils.json_path import Validator

        assert Validator.JSON(
            sample_data,
            "$.user.email",
            regex=r"^[\w\.-]+@[\w\.-]+\.\w+$"
        ) is True

    def test_validate_regex_no_match(self, sample_data):
        """Regex не совпадает"""
        from utils.json_path import Validator

        assert Validator.JSON(
            sample_data,
            "$.user.username",
            regex=r"^\d+$"
        ) is False

    # ========== Проверка слов ==========

    def test_validate_words_match(self, sample_data):
        """Слова найдены"""
        from utils.json_path import Validator

        assert Validator.JSON(
            sample_data,
            "$.user.role",
            words=["admin", "moderator"]
        ) is True

    def test_validate_words_no_match(self, sample_data):
        """Слова не найдены"""
        from utils.json_path import Validator

        assert Validator.JSON(
            sample_data,
            "$.user.role",
            words=["guest", "banned"]
        ) is False

    # ========== Комбинированные проверки ==========

    def test_validate_combined(self, sample_data):
        """Комбинация проверок"""
        from utils.json_path import Validator

        assert Validator.JSON(
            sample_data,
            "$.user.age",
            exists=True,
            is_type=int,
            range_value=(20, 30)
        ) is True

    def test_validate_array_elements(self, sample_data):
        """Валидация элементов массива"""
        from utils.json_path import Validator

        assert Validator.JSON(
            sample_data,
            "$.posts[*].published",
            value=True
        ) is True

    # ========== Невалидный JSON ==========

    def test_validate_invalid_json_exists_false(self):
        """Невалидный JSON + exists=False возвращает True"""
        from utils.json_path import Validator

        assert Validator.JSON("invalid", "$.field", exists=False) is True

    def test_validate_invalid_json_exists_true(self):
        """Невалидный JSON + exists=True возвращает False"""
        from utils.json_path import Validator

        assert Validator.JSON("invalid", "$.field", exists=True) is False