from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING, Any

import pytest
from hypothesis import strategies as st

if TYPE_CHECKING:
    import _pytest.config


class Secret:
    def __init__(self, value: Any) -> None:
        self.value = value

    def __repr__(self) -> str:
        return "Secret(********)"

    def __str___(self) -> str:
        return "*******"


def pytest_configure(config: _pytest.config.Config) -> None:
    # compute the CSS file’s absolute path from this file’s location
    project_root = Path(__file__).parent.parent
    css_file = project_root / "resources" / "pytest-html.css"
    # override whatever was in addopts
    config.option.css = [str(css_file)]

    # ensure we're still inlining it into the HTML
    if not config.option.self_contained_html:
        config.option.self_contained_html = True


# Hypothesis strategies for reusable test data generation
@pytest.fixture
def name_strategy() -> st.SearchStrategy[str]:
    """Hypothesis strategy for generating realistic names.

    Returns:
        Strategy that generates names suitable for greeting functions
    """
    return st.one_of(
        # Common names
        st.sampled_from(["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"]),
        # Short names
        st.text(
            alphabet=st.characters(whitelist_categories=("Lu", "Ll")),
            min_size=1,
            max_size=10,
        ),
        # Names with spaces
        st.text(
            alphabet=st.one_of(st.characters(whitelist_categories=("Lu", "Ll")), st.just(" ")),
            min_size=1,
            max_size=20,
        ).filter(lambda x: x.strip()),
    )


@pytest.fixture
def unicode_name_strategy() -> st.SearchStrategy[str]:
    """Hypothesis strategy for generating Unicode names.

    Returns:
        Strategy that generates names with various Unicode characters
    """
    return st.text(
        alphabet=st.characters(
            whitelist_categories=("Lu", "Ll", "Lt", "Lm", "Lo"),
            blacklist_characters={"\x00"},  # Exclude null character
        ),
        min_size=1,
        max_size=30,
    )


@pytest.fixture
def benchmark_names() -> list[str]:
    """Fixed set of names for consistent benchmark testing.

    Returns:
        List of names of varying lengths for performance testing
    """
    return [
        "A",  # 1 character
        "Alice",  # 5 characters
        "Christopher",  # 11 characters
        "Alexandra-Marie",  # 16 characters
        "A" * 50,  # 50 characters
        "B" * 100,  # 100 characters
        "🚀 Unicode Name 测试",  # Unicode with emoji
    ]


@pytest.fixture
def cli_test_scenarios() -> list[dict[str, Any]]:
    """Common CLI test scenarios for reuse across test modules.

    Returns:
        List of dictionaries with CLI test parameters
    """
    return [
        {"args": [], "expected_greeting": "Hi there"},
        {"args": ["Alice"], "expected_greeting": "Hi Alice"},
        {"args": ["Bob", "--json-logs"], "expected_greeting": "Hi Bob"},
        {
            "args": ["Charlie", "--log-level", "DEBUG"],
            "expected_greeting": "Hi Charlie",
        },
        {
            "args": ["Diana", "--json-logs", "--log-level", "ERROR"],
            "expected_greeting": "Hi Diana",
        },
    ]
