"""Benchmark tests for regexvalidate module.

These tests measure performance of key operations and are excluded from regular test runs.
Run with: pytest --benchmark-only or pytest -m benchmark
"""

from __future__ import annotations

import re

import pytest

from pytola.dev.regexvalidate.gui import RegexValidator


class TestBenchmarkRegexValidation:
    """Benchmark RegexValidator performance."""

    @pytest.fixture(scope="class")
    def simple_validator(self):
        """Genrate simple regex validator for basic benchmarking."""
        return RegexValidator(r"\d{3}-\d{2}-\d{4}")

    @pytest.fixture(scope="class")
    def complex_validator(self):
        """Complex regex validator for performance testing."""
        return RegexValidator(
            r"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"
        )

    @pytest.fixture(scope="class")
    def large_text(self):
        """Large text for testing performance with substantial input."""
        return " ".join([f"text-{i}-123-45-6789-more-text" for i in range(1000)])

    @pytest.mark.benchmark
    def test_simple_validation_performance(self, benchmark, simple_validator):
        """Benchmark simple regex validation."""
        text = "123-45-6789"
        result = benchmark(simple_validator.validate, text)
        assert result.is_valid is True

    @pytest.mark.benchmark
    def test_complex_validation_performance(self, benchmark, complex_validator):
        """Benchmark complex regex validation."""
        text = "192.168.1.1"
        result = benchmark(complex_validator.validate, text)
        assert result.is_valid is True

    @pytest.mark.benchmark
    def test_large_text_validation(self, benchmark, simple_validator, large_text):
        """Benchmark validation of large text input."""
        result = benchmark(simple_validator.validate, large_text)
        assert result.is_valid is True

    @pytest.mark.benchmark
    def test_find_all_matches_performance(self, benchmark, simple_validator, large_text):
        """Benchmark find_all_matches method."""
        matches = benchmark(simple_validator.find_all_matches, large_text)
        assert len(matches) > 0

    @pytest.mark.benchmark
    def test_pattern_compilation_performance(self, benchmark):
        """Benchmark pattern compilation overhead."""

        def compile_pattern():
            return RegexValidator(r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}")

        validator = benchmark(compile_pattern)
        assert validator is not None

    @pytest.mark.benchmark
    def test_multiple_validations_same_pattern(self, benchmark, simple_validator):
        """Benchmark multiple validations with same pattern."""
        texts = [f"{i:03d}-45-6789" for i in range(100)]

        def validate_multiple():
            results = []
            for text in texts:
                results.append(simple_validator.validate(text))
            return results

        results = benchmark(validate_multiple)
        assert len(results) == 100
        assert all(r.is_valid for r in results)

    @pytest.mark.benchmark
    def test_validator_creation_overhead(self, benchmark):
        """Benchmark the overhead of creating validator instances."""

        def create_validators():
            validators = []
            for i in range(100):
                validators.append(RegexValidator(f"pattern_{i}"))
            return validators

        validators = benchmark(create_validators)
        assert len(validators) == 100


class TestBenchmarkRawReVsValidator:
    """Benchmark raw re operations vs validator methods."""

    @pytest.mark.benchmark
    def test_raw_re_match_vs_validator(self, benchmark):
        """Compare raw re.match vs validator for simple patterns."""
        pattern = r"\d{3}-\d{2}-\d{4}"
        text = "123-45-6789"

        def raw_match():
            return re.match(pattern, text) is not None

        raw_result = benchmark(raw_match)
        assert raw_result is True

    @pytest.mark.benchmark
    def test_validator_match_vs_raw(self, benchmark):
        """Compare validator is_valid vs raw re.match."""
        pattern = r"\d{3}-\d{2}-\d{4}"
        text = "123-45-6789"
        validator = RegexValidator(pattern)

        def validator_match():
            return validator.is_valid(text)

        validator_result = benchmark(validator_match)
        assert validator_result is True


class TestBenchmarkRawReFindallVsValidator:
    """Benchmark raw re.findall vs validator find_all_matches."""

    @pytest.mark.benchmark
    def test_raw_re_findall(self, benchmark):
        """Benchmark raw re.findall performance."""
        pattern = r"\b\d+\b"
        text = "Numbers: 123, 456, 789 and text"

        def raw_findall():
            return re.findall(pattern, text)

        raw_matches = benchmark(raw_findall)
        assert len(raw_matches) == 3

    @pytest.mark.benchmark
    def test_validator_findall(self, benchmark):
        """Benchmark validator find_all_matches performance."""
        pattern = r"\b\d+\b"
        text = "Numbers: 123, 456, 789 and text"
        validator = RegexValidator(pattern)

        def validator_findall():
            return validator.find_all_matches(text)

        validator_matches = benchmark(validator_findall)
        assert len(validator_matches) == 3


class TestBenchmarkCompiledVsUncompiled:
    """Benchmark compiled vs uncompiled pattern performance."""

    @pytest.mark.benchmark
    def test_uncompiled_pattern_search(self, benchmark):
        """Benchmark uncompiled pattern search performance."""
        pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
        text = "Contact: user@example.com and admin@test.org"

        def uncompiled_search():
            return re.search(pattern, text)

        uncompiled_result = benchmark(uncompiled_search)
        assert uncompiled_result is not None

    @pytest.mark.benchmark
    def test_compiled_pattern_search(self, benchmark):
        """Benchmark compiled pattern search performance."""
        pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
        text = "Contact: user@example.com and admin@test.org"
        compiled_pattern = re.compile(pattern)

        def compiled_search():
            return compiled_pattern.search(text)

        compiled_result = benchmark(compiled_search)
        assert compiled_result is not None
